diff options
292 files changed, 25308 insertions, 1922 deletions
diff --git a/BUILD/compile-solaris-amd64-debug b/BUILD/compile-solaris-amd64-debug new file mode 100644 index 00000000000..ad1c298907f --- /dev/null +++ b/BUILD/compile-solaris-amd64-debug @@ -0,0 +1,10 @@ +#! /bin/sh +path=`dirname $0` +. "$path/SETUP.sh" +amd64_cflags="-m64 -mtune=athlon64" +extra_flags="$amd64_cflags $debug_cflags $max_cflags" +c_warnings="$c_warnings $debug_extra_warnings" +cxx_warnings="$cxx_warnings $debug_extra_warnings" +extra_configs="$amd64_configs $debug_configs $max_configs --enable-thread-safe-client" + +. "$path/FINISH.sh" diff --git a/BUILD/compile-solaris-amd64-forte b/BUILD/compile-solaris-amd64-forte new file mode 100644 index 00000000000..63aceb16c04 --- /dev/null +++ b/BUILD/compile-solaris-amd64-forte @@ -0,0 +1,52 @@ +#! /bin/sh + +gmake -k clean || true +/bin/rm -f */.deps/*.P config.cache + +path=`dirname $0` +. "$path/autorun.sh" + +# For "optimal" code for this computer add -fast to EXTRA +# To compile 64 bit, add -xarch=v9 to EXTRA_64_BIT + +EXTRA_64_BIT="-xarch=amd64" +EXTRA="-fast" + +# +# The following should not need to be touched +# + +export CC CXX CFLAGS CXXFLAGS +STD="-g -mt -D_FORTEC_ $EXTRA $EXTRA_64_BIT" +ASFLAGS="$EXTRA_64_BIT" +CC=cc-5.0 +CFLAGS="-Xa -xstrconst $STD" +CXX=CC +CXXFLAGS="-noex $STD" +./configure \ + --prefix=/usr/local/mysql \ + --localstatedir=/usr/local/mysql/data \ + --libexecdir=/usr/local/mysql/bin \ + --with-extra-charsets=complex \ + --enable-thread-safe-client \ + --enable-local-infile \ + --with-zlib-dir=bundled \ + --with-big-tables \ + --with-readline \ + --with-archive-storage-engine \ + --with-named-curses=-lcurses \ + --with-big-tables \ + --with-innodb \ + --with-example-storage-engine \ + --with-blackhole-storage-engine \ + --with-federated-storage-engine \ + --with-csv-storage-engine \ + --with-ssl \ + --enable-assembler + +# Not including: +# --with-ndbcluster +# --with-berkeley-db + +gmake -j4 +test $? = 0 && make test diff --git a/BUILD/compile-solaris-amd64-forte-debug b/BUILD/compile-solaris-amd64-forte-debug new file mode 100644 index 00000000000..8e3ade9b429 --- /dev/null +++ b/BUILD/compile-solaris-amd64-forte-debug @@ -0,0 +1,54 @@ +#! /bin/sh + +gmake -k clean || true +/bin/rm -f */.deps/*.P config.cache + +path=`dirname $0` +. "$path/autorun.sh" + +# To compile 64 bit, add -xarch=amd64 to EXTRA_64_BIT +EXTRA_64_BIT="-xarch=amd64" + +# For "optimal" code for this computer add -fast to EXTRA. Note that +# this causes problem with debugging the program since -fast implies +# -xO5. +EXTRA="" + +# +# The following should not need to be touched +# + +export CC CXX CFLAGS CXXFLAGS +STD="-g -mt -D_FORTEC_ $EXTRA $EXTRA_64_BIT $debug_cflags" +ASFLAGS="$EXTRA_64_BIT" +CC=cc-5.0 +CFLAGS="-Xa -xstrconst $STD" +CXX=CC +CXXFLAGS="-noex $STD" +./configure \ + --prefix=/usr/local/mysql \ + --localstatedir=/usr/local/mysql/data \ + --libexecdir=/usr/local/mysql/bin \ + --with-extra-charsets=complex \ + --enable-thread-safe-client \ + --enable-local-infile \ + --with-zlib-dir=bundled \ + --with-big-tables \ + --with-readline \ + --with-archive-storage-engine \ + --with-named-curses=-lcurses \ + --with-big-tables \ + --with-innodb \ + --with-example-storage-engine \ + --with-blackhole-storage-engine \ + --with-federated-storage-engine \ + --with-csv-storage-engine \ + --with-ssl \ + --with-debug \ + --enable-assembler + +# Not including: +# --with-ndbcluster +# --with-berkeley-db + +gmake -j4 diff --git a/client/client_priv.h b/client/client_priv.h index 71d6ce8a635..06145232995 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -76,7 +76,7 @@ enum options_client OPT_SLAP_POST_SYSTEM, OPT_SLAP_COMMIT, OPT_SLAP_DETACH, - OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT, OPT_SERVER_ID, + OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT_MODE, OPT_SERVER_ID, OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT, OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE, OPT_WRITE_BINLOG, OPT_DUMP_DATE, diff --git a/client/mysql.cc b/client/mysql.cc index 8f118a06935..1d673348f58 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -3113,7 +3113,10 @@ com_connect(String *buffer, char *line) Two null bytes are needed in the end of buff to allow get_arg to find end of string the second time it's called. */ - strmake(buff, line, sizeof(buff)-2); + tmp= strmake(buff, line, sizeof(buff)-2); +#ifdef EXTRA_DEBUG + tmp[1]= 0; +#endif tmp= get_arg(buff, 0); if (tmp && *tmp) { diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 7a4135ab649..8b79266d749 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -63,7 +63,12 @@ void sql_print_error(const char *format, ...); static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0; static bool opt_hexdump= 0; -static bool opt_base64_output= 0; +const char *base64_output_mode_names[]= {"NEVER", "AUTO", "ALWAYS", NullS}; +TYPELIB base64_output_mode_typelib= + { array_elements(base64_output_mode_names) - 1, "", + base64_output_mode_names, NULL }; +static enum_base64_output_mode opt_base64_output_mode= BASE64_OUTPUT_UNSPEC; +static const char *opt_base64_output_mode_str= NullS; static const char* database= 0; static my_bool force_opt= 0, short_form= 0, remote_opt= 0; static my_bool debug_info_flag, debug_check_flag; @@ -96,7 +101,7 @@ static my_bool file_not_closed_error= 0; This is because the event will be created (alloced) in read_log_event() (which returns a pointer) in check_header(). */ -Format_description_log_event* glob_description_event; +static Format_description_log_event* glob_description_event; static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, const char* logname); @@ -265,7 +270,7 @@ public: File prepare_new_file_for_old_format(Load_log_event *le, char *filename); int load_old_format_file(NET* net, const char *server_fname, uint server_fname_len, File file); - int process_first_event(const char *bname, uint blen, const char *block, + int process_first_event(const char *bname, uint blen, const uchar *block, uint block_len, uint file_id, Create_file_log_event *ce); }; @@ -370,7 +375,7 @@ int Load_log_processor::load_old_format_file(NET* net, const char*server_fname, */ int Load_log_processor::process_first_event(const char *bname, uint blen, - const char *block, uint block_len, + const uchar *block, uint block_len, uint file_id, Create_file_log_event *ce) { @@ -557,7 +562,7 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, else print_event_info->hexdump_from= pos; - print_event_info->base64_output= opt_base64_output; + print_event_info->base64_output_mode= opt_base64_output_mode; DBUG_PRINT("debug", ("event_type: %s", ev->get_type_str())); @@ -565,7 +570,7 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, case QUERY_EVENT: if (check_database(((Query_log_event*)ev)->db)) goto end; - if (opt_base64_output) + if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) write_event_header_and_base64(ev, result_file, print_event_info); else ev->print(result_file, print_event_info); @@ -589,7 +594,7 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, filename and use LOCAL), prepared in the 'case EXEC_LOAD_EVENT' below. */ - if (opt_base64_output) + if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) { write_event_header_and_base64(ce, result_file, print_event_info); } @@ -670,6 +675,13 @@ Create_file event for file_id: %u\n",exv->file_id); if (fname) { + /* + Fix the path so it can be consumed by mysql client (requires Unix path). + */ + int stop= strlen(fname); + for (int i= 0; i < stop; i++) + if (fname[i] == '\\') + fname[i]= '/'; exlq->print(result_file, print_event_info, fname); my_free(fname, MYF(MY_WME)); } @@ -678,6 +690,38 @@ Create_file event for file_id: %u\n",exv->file_id); Begin_load_query event for file_id: %u\n", exlq->file_id); break; } + case TABLE_MAP_EVENT: + case WRITE_ROWS_EVENT: + case DELETE_ROWS_EVENT: + case UPDATE_ROWS_EVENT: + case PRE_GA_WRITE_ROWS_EVENT: + case PRE_GA_DELETE_ROWS_EVENT: + case PRE_GA_UPDATE_ROWS_EVENT: + /* + These events must be printed in base64 format, if printed. + base64 format requires a FD event to be safe, so if no FD + event has been printed, we give an error. Except if user + passed --short-form, because --short-form disables printing + row events. + */ + if (!print_event_info->printed_fd_event && !short_form) + { + /* + todo: a lot to clean up here + */ + const char* type_str= ev->get_type_str(); + delete ev; + if (opt_base64_output_mode == BASE64_OUTPUT_NEVER) + die("--base64-output=never specified, but binlog contains a " + "%s event which must be printed in base64.", + type_str); + else + die("malformed binlog: it does not contain any " + "Format_description_log_event. I now found a %s event, which is " + "not safe to process without a Format_description_log_event.", + type_str); + } + /* FALL THROUGH */ default: ev->print(result_file, print_event_info); } @@ -707,12 +751,17 @@ static struct my_option my_long_options[] = {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"base64-output", OPT_BASE64_OUTPUT, - "Print all binlog entries using base64 encoding. " - "This is for debugging only. Logs produced using this option " - "should not be applied on production systems.", - (uchar**) &opt_base64_output, (uchar**) &opt_base64_output, 0, GET_BOOL, - NO_ARG, 0, 0, 0, 0, 0, 0}, + {"base64-output", OPT_BASE64_OUTPUT_MODE, + "Determine when the output statements should be base64-encoded BINLOG " + "statements: 'never' disables it and works only for binlogs without " + "row-based events; 'auto' is the default and prints base64 only when " + "necessary (i.e., for row-based events and format description events); " + "'always' prints base64 whenever possible. 'always' is for debugging " + "only and should not be used in a production system. The default is " + "'auto'. --base64-output is a short form for --base64-output=always." + ,(uchar**) &opt_base64_output_mode_str, + (uchar**) &opt_base64_output_mode_str, + 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, /* mysqlbinlog needs charsets knowledge, to be able to convert a charset number found in binlog to a charset name (to be able to print things @@ -788,7 +837,10 @@ static struct my_option my_long_options[] = {"set-charset", OPT_SET_CHARSET, "Add 'SET NAMES character_set' to the output.", (uchar**) &charset, (uchar**) &charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"short-form", 's', "Just show the queries, no extra info.", + {"short-form", 's', "Just show regular queries: no extra info and no " + "row-based events. This is for testing only, and should not be used in " + "production systems. If you want to suppress base64-output, consider " + "using --base64-output=never instead.", (uchar**) &short_form, (uchar**) &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"socket", 'S', "Socket file to use for connection.", @@ -973,6 +1025,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case OPT_STOP_DATETIME: stop_datetime= convert_str_to_timestamp(stop_datetime_str); break; + case OPT_BASE64_OUTPUT_MODE: + if (argument == NULL) + opt_base64_output_mode= BASE64_OUTPUT_ALWAYS; + else + { + opt_base64_output_mode= (enum_base64_output_mode) + (find_type_or_exit(argument, &base64_output_mode_typelib, opt->name)-1); + } + break; case 'V': print_version(); exit(0); @@ -1305,8 +1366,31 @@ err: } +/** + Reads the @c Format_description_log_event from the beginning of the + input file. + + The @c Format_description_log_event is only read if it is outside + the range specified with @c --start-position; otherwise, it will be + seen later. If this is an old binlog, a fake @c + Format_description_event is created. This also prints a @c + Format_description_log_event to the output, unless we reach the + --start-position range. In this case, it is assumed that a @c + Format_description_log_event will be found when reading events the + usual way. + + @param file The file to which a @c Format_description_log_event will + be printed. + + @param description_event Pointer to the global @c + Format_description_log_event pointer. This will be updated if a new + Format_description_log_event is found. + + @param print_event_info Context state needed to print events. +*/ static void check_header(IO_CACHE* file, - Format_description_log_event **description_event) + Format_description_log_event **description_event, + PRINT_EVENT_INFO *print_event_info) { uchar header[BIN_LOG_HEADER_SIZE]; uchar buf[PROBE_HEADER_LEN]; @@ -1369,10 +1453,12 @@ Could not read entry at offset %lu : Error in log format or read error", } else { - DBUG_PRINT("info",("buf[4]=%d", buf[4])); + DBUG_PRINT("info",("buf[EVENT_TYPE_OFFSET=%d]=%d", + EVENT_TYPE_OFFSET, buf[EVENT_TYPE_OFFSET])); /* always test for a Start_v3, even if no --start-position */ - if (buf[4] == START_EVENT_V3) /* This is 3.23 or 4.x */ + if (buf[EVENT_TYPE_OFFSET] == START_EVENT_V3) { + /* This is 3.23 or 4.x */ if (uint4korr(buf + EVENT_LEN_OFFSET) < (LOG_EVENT_MINIMAL_HEADER_LEN + START_V3_HEADER_LEN)) { @@ -1384,8 +1470,9 @@ Could not read entry at offset %lu : Error in log format or read error", } else if (tmp_pos >= start_position) break; - else if (buf[4] == FORMAT_DESCRIPTION_EVENT) /* This is 5.0 */ + else if (buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) { + /* This is 5.0 */ Format_description_log_event *new_description_event; my_b_seek(file, tmp_pos); /* seek back to event's start */ if (!(new_description_event= (Format_description_log_event*) @@ -1397,11 +1484,22 @@ Could not read entry at offset %lu : Error in log format or read error", at offset %lu ; this could be a log format error or read error", tmp_pos); } - delete *description_event; - *description_event= new_description_event; + if (opt_base64_output_mode == BASE64_OUTPUT_AUTO + || opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) + /* + process_event will delete *description_event and set it to + the new one, so we should not do it ourselves in this + case. + */ + process_event(print_event_info, new_description_event, tmp_pos); + else + { + delete *description_event; + *description_event= new_description_event; + } DBUG_PRINT("info",("Setting description_event")); } - else if (buf[4] == ROTATE_EVENT) + else if (buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT) { Log_event *ev; my_b_seek(file, tmp_pos); /* seek back to event's start */ @@ -1430,7 +1528,7 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, uchar tmp_buff[BIN_LOG_HEADER_SIZE]; int error= 0; - if (logname && logname[0] != '-') + if (logname && strcmp(logname, "-") != 0) { if ((fd = my_open(logname, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0) return 1; @@ -1440,7 +1538,7 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, my_close(fd, MYF(MY_WME)); return 1; } - check_header(file, &glob_description_event); + check_header(file, &glob_description_event, print_event_info); } else // reading from stdin; { @@ -1462,7 +1560,7 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, if (init_io_cache(file, fileno(stdin), 0, READ_CACHE, (my_off_t) 0, 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE))) return 1; - check_header(file, &glob_description_event); + check_header(file, &glob_description_event, print_event_info); if (start_position) { /* skip 'start_position' characters from stdin */ @@ -1554,6 +1652,9 @@ int main(int argc, char** argv) exit(1); } + if (opt_base64_output_mode == BASE64_OUTPUT_UNSPEC) + opt_base64_output_mode= BASE64_OUTPUT_AUTO; + my_set_max_open_files(open_files_limit); MY_TMPDIR tmpdir; diff --git a/client/mysqldump.c b/client/mysqldump.c index 01b484e924e..f119e0b40b0 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -590,7 +590,9 @@ static void write_header(FILE *sql_file, char *db_name) { if (opt_comments) { - fprintf(sql_file, "-- MySQL dump %s\n--\n", DUMP_VERSION); + fprintf(sql_file, + "-- MySQL dump %s Distrib %s, for %s (%s)\n--\n", + DUMP_VERSION, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); fprintf(sql_file, "-- Host: %s Database: %s\n", current_host ? current_host : "localhost", db_name ? db_name : ""); diff --git a/client/mysqltest.c b/client/mysqltest.c index dbf6c999478..55d8dc22c41 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -3688,7 +3688,7 @@ void do_get_file_name(struct st_command *command, if (*p) *p++= 0; command->last_argument= p; - strmake(dest, name, dest_max_len); + strmake(dest, name, dest_max_len - 1); } @@ -7024,7 +7024,7 @@ int main(int argc, char **argv) if (save_file[0]) { - strmake(command->require_file, save_file, sizeof(save_file)); + strmake(command->require_file, save_file, sizeof(save_file) - 1); save_file[0]= 0; } run_query(cur_con, command, flags); diff --git a/configure.in b/configure.in index cf36044771e..953c4507343 100644 --- a/configure.in +++ b/configure.in @@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM # # When changing major version number please also check switch statement # in mysqlbinlog::check_master_version(). -AM_INIT_AUTOMAKE(mysql, 5.1.23-maria-alpha) +AM_INIT_AUTOMAKE(mysql, 5.1.24-maria-alpha) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 @@ -837,6 +837,7 @@ AC_CHECK_FUNC(p2open, , AC_CHECK_LIB(gen, p2open)) AC_CHECK_FUNC(bind, , AC_CHECK_LIB(bind, bind)) # Check if crypt() exists in libc or libcrypt, sets LIBS if needed AC_SEARCH_LIBS(crypt, crypt, AC_DEFINE(HAVE_CRYPT, 1, [crypt])) +# See if we need a library for address lookup. AC_SEARCH_LIBS(inet_aton, [socket nsl resolv]) # For the sched_yield() function on Solaris @@ -1726,6 +1727,30 @@ case "$with_atomic_ops" in *) AC_MSG_ERROR(["$with_atomic_ops" is not a valid value for --with-atomic-ops]) ;; esac +AC_CACHE_CHECK([whether the compiler provides atomic builtins], + [mysql_cv_gcc_atomic_builtins], [AC_TRY_RUN([ + int main() + { + int foo= -10; int bar= 10; + if (!__sync_fetch_and_add(&foo, bar) || foo) + return -1; + bar= __sync_lock_test_and_set(&foo, bar); + if (bar || foo != 10) + return -1; + bar= __sync_val_compare_and_swap(&bar, foo, 15); + if (bar) + return -1; + return 0; + } +], [mysql_cv_gcc_atomic_builtins=yes], + [mysql_cv_gcc_atomic_builtins=no], + [mysql_cv_gcc_atomic_builtins=no])]) + +if test "x$mysql_cv_gcc_atomic_builtins" = xyes; then + AC_DEFINE(HAVE_GCC_ATOMIC_BUILTINS, 1, + [Define to 1 if compiler provides atomic builtins.]) +fi + # Force static compilation to avoid linking problems/get more speed AC_ARG_WITH(mysqld-ldflags, [ --with-mysqld-ldflags Extra linking arguments for mysqld], diff --git a/extra/resolveip.c b/extra/resolveip.c index b61c0871aaf..e5fede7fda8 100644 --- a/extra/resolveip.c +++ b/extra/resolveip.c @@ -116,11 +116,13 @@ int main(int argc, char **argv) while (argc--) { + struct in_addr addr; ip = *argv++; - if (my_isdigit(&my_charset_latin1,ip[0])) + /* Not compatible with IPv6! Probably should use getnameinfo(). */ + if (inet_aton(ip, &addr) != 0) { - taddr = inet_addr(ip); + taddr= addr.s_addr; if (taddr == htonl(INADDR_BROADCAST)) { puts("Broadcast"); diff --git a/include/Makefile.am b/include/Makefile.am index 400c6976e5b..2155571cd5a 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -36,7 +36,7 @@ noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \ mysql_version.h.in my_handler.h my_time.h \ my_vle.h my_user.h my_atomic.h atomic/nolock.h \ atomic/rwlock.h atomic/x86-gcc.h atomic/generic-msvc.h \ - my_libwrap.h wqueue.h + atomic/gcc_builtins.h my_libwrap.h wqueue.h # Remove built files and the symlinked directories CLEANFILES = $(BUILT_SOURCES) readline openssl diff --git a/include/atomic/gcc_builtins.h b/include/atomic/gcc_builtins.h new file mode 100644 index 00000000000..509701b30a5 --- /dev/null +++ b/include/atomic/gcc_builtins.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2008 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 */ + +#define make_atomic_add_body(S) \ + v= __sync_fetch_and_add(a, v); +#define make_atomic_swap_body(S) \ + v= __sync_lock_test_and_set(a, v); +#define make_atomic_cas_body(S) \ + int ## S sav; \ + sav= __sync_val_compare_and_swap(a, *cmp, set); \ + if (!(ret= (sav == *cmp))) *cmp= sav; + +#ifdef MY_ATOMIC_MODE_DUMMY +#define make_atomic_load_body(S) ret= *a +#define make_atomic_store_body(S) *a= v +#else +#define make_atomic_load_body(S) \ + ret= __sync_fetch_and_or(a, 0); +#define make_atomic_store_body(S) \ + (void) __sync_lock_test_and_set(a, v); +#endif diff --git a/include/atomic/nolock.h b/include/atomic/nolock.h index 59497d34c11..cafd916981d 100644 --- a/include/atomic/nolock.h +++ b/include/atomic/nolock.h @@ -13,7 +13,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#if defined(__i386__) || defined(_MSC_VER) || defined(__x86_64__) +#if defined(__i386__) || defined(_MSC_VER) || \ + defined(__x86_64__) || defined(HAVE_GCC_ATOMIC_BUILTINS) # ifdef MY_ATOMIC_MODE_DUMMY # define LOCK_prefix "" @@ -21,7 +22,9 @@ # define LOCK_prefix "lock" # endif -# ifdef __GNUC__ +# ifdef HAVE_GCC_ATOMIC_BUILTINS +# include "gcc_builtins.h" +# elif __GNUC__ # include "x86-gcc.h" # elif defined(_MSC_VER) # include "generic-msvc.h" diff --git a/include/my_bitmap.h b/include/my_bitmap.h index ab69b2d671d..78642df3362 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -159,6 +159,22 @@ static inline my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2) #define bitmap_set_all(MAP) \ (memset((MAP)->bitmap, 0xFF, 4*no_words_in_map((MAP)))) +/** + check, set and clear a bit of interest of an integer. + + If the bit is out of range @retval -1. Otherwise + bit_is_set @return 0 or 1 reflecting the bit is set or not; + bit_do_set @return 1 (bit is set 1) + bit_do_clear @return 0 (bit is cleared to 0) +*/ + +#define bit_is_set(I,B) (sizeof(I) * CHAR_BIT > (B) ? \ + (((I) & (ULL(1) << (B))) == 0 ? 0 : 1) : -1) +#define bit_do_set(I,B) (sizeof(I) * CHAR_BIT > (B) ? \ + ((I) |= (ULL(1) << (B)), 1) : -1) +#define bit_do_clear(I,B) (sizeof(I) * CHAR_BIT > (B) ? \ + ((I) &= ~(ULL(1) << (B)), 0) : -1) + #ifdef __cplusplus } #endif diff --git a/include/my_sys.h b/include/my_sys.h index 363f3a12e64..0e670f4d965 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -539,6 +539,11 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *); #define my_b_tell(info) ((info)->pos_in_file + \ (size_t) (*(info)->current_pos - (info)->request_pos)) +#define my_b_get_buffer_start(info) (info)->request_pos +#define my_b_get_bytes_in_buffer(info) (char*) (info)->read_end - \ + (char*) my_b_get_buffer_start(info) +#define my_b_get_pos_in_file(info) (info)->pos_in_file + /* tell write offset in the SEQ_APPEND cache */ int my_b_copy_to_file(IO_CACHE *cache, FILE *file); my_off_t my_b_append_tell(IO_CACHE* info); diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 79d11c857ab..a77dccdebf2 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -45,7 +45,8 @@ dist-hook: $(distdir)/std_data/ndb_backup51_data_be \ $(distdir)/std_data/ndb_backup51_data_le \ $(distdir)/std_data/parts \ - $(distdir)/lib + $(distdir)/lib \ + $(distdir)/lib/My -$(INSTALL_DATA) $(srcdir)/t/*.def $(distdir)/t $(INSTALL_DATA) $(srcdir)/t/*.test $(distdir)/t -$(INSTALL_DATA) $(srcdir)/t/*.imtest $(distdir)/t @@ -58,6 +59,7 @@ dist-hook: -$(INSTALL_DATA) $(srcdir)/extra/binlog_tests/*.opt $(distdir)/extra/binlog_tests -$(INSTALL_DATA) $(srcdir)/extra/rpl_tests/*.opt $(distdir)/extra/rpl_tests $(INSTALL_DATA) $(srcdir)/include/*.inc $(distdir)/include + $(INSTALL_DATA) $(srcdir)/include/*.sql $(distdir)/include $(INSTALL_DATA) $(srcdir)/include/*.test $(distdir)/include $(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.require $(distdir)/r $(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(distdir)/std_data @@ -74,6 +76,7 @@ dist-hook: $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_le/BACKUP* $(distdir)/std_data/ndb_backup51_data_le $(INSTALL_DATA) $(srcdir)/std_data/parts/part_* $(distdir)/std_data/parts $(INSTALL_DATA) $(srcdir)/lib/*.pl $(distdir)/lib + $(INSTALL_DATA) $(srcdir)/lib/My/*.pm $(distdir)/lib/My -rm -rf `find $(distdir)/suite -type d -name SCCS` $(distdir)/suite/row_lock install-data-local: @@ -89,7 +92,8 @@ install-data-local: $(DESTDIR)$(testdir)/std_data/ndb_backup51_data_be \ $(DESTDIR)$(testdir)/std_data/ndb_backup51_data_le \ $(DESTDIR)$(testdir)/std_data/parts \ - $(DESTDIR)$(testdir)/lib + $(DESTDIR)$(testdir)/lib \ + $(DESTDIR)$(testdir)/lib/My $(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(testdir) -$(INSTALL_DATA) $(srcdir)/t/*.def $(DESTDIR)$(testdir)/t $(INSTALL_DATA) $(srcdir)/t/*.test $(DESTDIR)$(testdir)/t @@ -106,6 +110,7 @@ install-data-local: -$(INSTALL_DATA) $(srcdir)/extra/binlog_tests/*.opt $(DESTDIR)$(testdir)/extra/binlog_tests -$(INSTALL_DATA) $(srcdir)/extra/rpl_tests/*.opt $(DESTDIR)$(testdir)/extra/rpl_tests $(INSTALL_DATA) $(srcdir)/include/*.inc $(DESTDIR)$(testdir)/include + $(INSTALL_DATA) $(srcdir)/include/*.sql $(DESTDIR)$(testdir)/include $(INSTALL_DATA) $(srcdir)/include/*.test $(DESTDIR)$(testdir)/include $(INSTALL_DATA) $(srcdir)/std_data/*.dat $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.*001 $(DESTDIR)$(testdir)/std_data @@ -123,6 +128,7 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_le/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup51_data_le $(INSTALL_DATA) $(srcdir)/std_data/parts/part_* $(DESTDIR)$(testdir)/std_data/parts $(INSTALL_DATA) $(srcdir)/lib/*.pl $(DESTDIR)$(testdir)/lib + $(INSTALL_DATA) $(srcdir)/lib/My/*.pm $(DESTDIR)$(testdir)/lib/My for f in `(cd $(srcdir); find suite -type f | egrep -v 'SCCS|row_lock')`; \ do \ d=$(DESTDIR)$(testdir)/`dirname $$f`; \ diff --git a/mysql-test/extra/binlog_tests/blackhole.test b/mysql-test/extra/binlog_tests/blackhole.test index df2295af4ff..59d31c3a08b 100644 --- a/mysql-test/extra/binlog_tests/blackhole.test +++ b/mysql-test/extra/binlog_tests/blackhole.test @@ -126,7 +126,12 @@ select * from t2; select * from t3; let $VERSION=`select version()`; -source include/show_binlog_events.inc; +--replace_result $VERSION VERSION +--replace_column 2 # 4 # 5 # +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ +--replace_regex /file_id=[0-9]+/file_id=#/ +show binlog events; + drop table t1,t2,t3; # @@ -178,7 +183,14 @@ start transaction; insert into t1 values(2); rollback; set autocommit=1; -source include/show_binlog_events.inc; + +let $VERSION=`select version()`; +--replace_result $VERSION VERSION +--replace_column 2 # 4 # 5 # +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ +--replace_regex /file_id=[0-9]+/file_id=#/ +show binlog events; + drop table if exists t1; # End of 5.1 tests diff --git a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test index 7141bd1abb9..6ac8a89591a 100644 --- a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test +++ b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test @@ -315,4 +315,324 @@ disconnect con3; connection con4; select get_lock("a",10); # wait for rollback to finish +flush logs; + +# we check that the error code of the "ROLLBACK" event is 0 and not +# ER_SERVER_SHUTDOWN (i.e. disconnection just rolls back transaction +# and does not make slave to stop) +if (`select @@binlog_format = 'ROW'`) +{ + --exec $MYSQL_BINLOG --start-position=524 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output +} + +if (`select @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`) +{ + --exec $MYSQL_BINLOG --start-position=555 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output +} + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval select +(@a:=load_file("$MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output")) +is not null; +--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR +eval select +@a like "%#%error_code=0%ROLLBACK\\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" OR +@a like "%#%error_code=0%ROLLBACK\\r\\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%", +@a not like "%#%error_code=%error_code=%"; +drop table t1, t2; + +# +# Bug #27417 thd->no_trans_update.stmt lost value inside of SF-exec-stack +# bug #28960 non-trans temp table changes with insert .. select +# not binlogged after rollback +# +# testing appearence of insert into temp_table in binlog. +# There are two branches of execution that require different setup. + +## send_eof() branch + +# prepare + +create temporary table tt (a int unique); +create table ti (a int) engine=innodb; +reset master; + +# action + +begin; +insert into ti values (1); +insert into ti values (2) ; +insert into tt select * from ti; +rollback; + +# check + +select count(*) from tt /* 2 */; +source include/show_binlog_events.inc; +select count(*) from ti /* zero */; +insert into ti select * from tt; +select * from ti /* that is what slave would miss - a bug */; + + +## send_error() branch +delete from ti; +delete from tt where a=1; +reset master; + +# action + +begin; +insert into ti values (1); +insert into ti values (2) /* to make the dup error in the following */; +--error ER_DUP_ENTRY +insert into tt select * from ti /* one affected and error */; +rollback; + +# check + +source include/show_binlog_events.inc; +select count(*) from ti /* zero */; +insert into ti select * from tt; +select * from tt /* that is what otherwise slave missed - the bug */; + +drop table ti, tt; + + +# +# Bug #27417 thd->no_trans_update.stmt lost value inside of SF-exec-stack +# +# Testing asserts: if there is a side effect of modifying non-transactional +# table thd->no_trans_update.stmt must be TRUE; +# the assert is active with debug build +# + +--disable_warnings +drop function if exists bug27417; +drop table if exists t1,t2; +--enable_warnings +# side effect table +CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM; +# target tables +CREATE TABLE t2 (a int NOT NULL auto_increment, PRIMARY KEY (a)); + +delimiter |; +create function bug27417(n int) +RETURNS int(11) +begin + insert into t1 values (null); + return n; +end| +delimiter ;| + +reset master; + +# execute + +insert into t2 values (bug27417(1)); +insert into t2 select bug27417(2); +reset master; + +--error ER_DUP_ENTRY +insert into t2 values (bug27417(2)); +source include/show_binlog_events.inc; /* only (!) with fixes for #23333 will show there is the query */; +select count(*) from t1 /* must be 3 */; + +reset master; +select count(*) from t2; +delete from t2 where a=bug27417(3); +select count(*) from t2 /* nothing got deleted */; +source include/show_binlog_events.inc; /* the query must be in regardless of #23333 */; +select count(*) from t1 /* must be 5 */; + +--enable_info +delete t2 from t2 where t2.a=bug27417(100) /* must not affect t2 */; +--disable_info +select count(*) from t1 /* must be 7 */; + +# function bug27417 remains for the following testing of bug#23333 +drop table t1,t2; + +# +# Bug#23333 using the patch (and the test) for bug#27471 +# +# throughout the bug tests +# t1 - non-trans side effects gatherer; +# t2 - transactional table; +# + +CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM; +CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB; +CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique) ENGINE=MyISAM; +CREATE TABLE t4 (a int, PRIMARY KEY (a), b int unique) ENGINE=Innodb; +CREATE TABLE t5 (a int, PRIMARY KEY (a)) ENGINE=InnoDB; + + +# +# INSERT +# + +# prepare + + insert into t2 values (1); + reset master; + +# execute + + --error ER_DUP_ENTRY + insert into t2 values (bug27417(1)); + +# check + + source include/show_binlog_events.inc; /* the output must denote there is the query */; + select count(*) from t1 /* must be 1 */; + +# +# INSERT SELECT +# + +# prepare + delete from t1; + delete from t2; + insert into t2 values (2); + reset master; + +# execute + + --error ER_DUP_ENTRY + insert into t2 select bug27417(1) union select bug27417(2); + +# check + + source include/show_binlog_events.inc; /* the output must denote there is the query */; + select count(*) from t1 /* must be 2 */; + +# +# UPDATE inc multi-update +# + +# prepare + delete from t1; + insert into t3 values (1,1),(2,3),(3,4); + reset master; + +# execute + --error ER_DUP_ENTRY + update t3 set b=b+bug27417(1); + +# check + source include/show_binlog_events.inc; /* the output must denote there is the query */; + select count(*) from t1 /* must be 2 */; + +## multi_update::send_eof() branch + +# prepare + delete from t3; + delete from t4; + insert into t3 values (1,1); + insert into t4 values (1,1),(2,2); + + reset master; + +# execute + --error ER_DUP_ENTRY + UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */; + +# check + source include/show_binlog_events.inc; /* the output must denote there is the query */; + select count(*) from t1 /* must be 4 */; + +## send_error() branch of multi_update + +# prepare + delete from t1; + delete from t3; + delete from t4; + insert into t3 values (1,1),(2,2); + insert into t4 values (1,1),(2,2); + + reset master; + +# execute + --error ER_DUP_ENTRY + UPDATE t3,t4 SET t3.a=t4.a + bug27417(1); + +# check + select count(*) from t1 /* must be 1 */; + +# cleanup + drop table t4; + + +# +# DELETE incl multi-delete +# + +# prepare + delete from t1; + delete from t2; + delete from t3; + insert into t2 values (1); + insert into t3 values (1,1); + create trigger trg_del before delete on t2 for each row + insert into t3 values (bug27417(1), 2); + reset master; + +# execute + --error ER_DUP_ENTRY + delete from t2; +# check + source include/show_binlog_events.inc; /* the output must denote there is the query */; + select count(*) from t1 /* must be 1 */; + +# cleanup + drop trigger trg_del; + +# prepare + delete from t1; + delete from t2; + delete from t5; + create trigger trg_del_t2 after delete on t2 for each row + insert into t1 values (1); + insert into t2 values (2),(3); + insert into t5 values (1),(2); + reset master; + +# execute + --error ER_DUP_ENTRY + delete t2.* from t2,t5 where t2.a=t5.a + 1; + +# check + source include/show_binlog_events.inc; /* the output must denote there is the query */; + select count(*) from t1 /* must be 1 */; + + +# +# LOAD DATA +# + +# prepare + delete from t1; + create table t4 (a int default 0, b int primary key) engine=innodb; + insert into t4 values (0, 17); + reset master; + +# execute + --error ER_DUP_ENTRY + load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2); +# check + select * from t4; + select count(*) from t1 /* must be 2 */; + source include/show_binlog_events.inc; /* the output must denote there is the query */; + +# +# bug#23333 cleanup +# + + +drop trigger trg_del_t2; +drop table t1,t2,t3,t4,t5; +drop function bug27417; + + +--echo end of tests diff --git a/mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test b/mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test index 03514bfdb55..0a0bef4ca4d 100644 --- a/mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test +++ b/mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test @@ -18,7 +18,6 @@ create temporary table tt (a int unique); create table ti (a int) engine=innodb; reset master; -show master status; # action @@ -31,7 +30,6 @@ rollback; # check select count(*) from tt /* 2 */; -show master status; source include/show_binlog_events.inc; select count(*) from ti /* zero */; insert into ti select * from tt; @@ -42,7 +40,6 @@ select * from ti /* that is what slave would miss - bug#28960 */; delete from ti; delete from tt where a=1; reset master; -show master status; # action @@ -55,7 +52,6 @@ rollback; # check -show master status; source include/show_binlog_events.inc; # nothing in binlog with row bilog format select count(*) from ti /* zero */; insert into ti select * from tt; diff --git a/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test b/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test index efca53d5698..5abd04b98ef 100644 --- a/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test +++ b/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test @@ -419,7 +419,7 @@ connection master; update t31 set f5=555555555555555 where f3=6; update t31 set f2=2 where f3=2; update t31 set f1=NULL where f3=1; - update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; + update t31 set f3=0, f27=NULL, f35='f35 new value' where f3=3; --echo --echo ** Delete from Master ** diff --git a/mysql-test/extra/rpl_tests/rpl_foreign_key.test b/mysql-test/extra/rpl_tests/rpl_foreign_key.test index 583f2d85554..8755bf5aa87 100644 --- a/mysql-test/extra/rpl_tests/rpl_foreign_key.test +++ b/mysql-test/extra/rpl_tests/rpl_foreign_key.test @@ -32,3 +32,34 @@ SET FOREIGN_KEY_CHECKS=0; DROP TABLE IF EXISTS t1,t2,t3; SET FOREIGN_KEY_CHECKS=1; sync_slave_with_master; + +# +# Bug #32468 delete rows event on a table with foreign key constraint fails +# + +connection master; + +eval create table t1 (b int primary key) engine = $engine_type; +eval create table t2 (a int primary key, b int, foreign key (b) references t1(b)) + engine = $engine_type; + +insert into t1 set b=1; +insert into t2 set a=1, b=1; + +set foreign_key_checks=0; +set @@session.binlog_format=row; +delete from t1; + +--echo must sync w/o a problem (could not with the buggy code) +sync_slave_with_master; +select count(*) from t1 /* must be zero */; + + +# cleanup for bug#32468 + +connection master; +drop table t2,t1; + +sync_slave_with_master; + + diff --git a/mysql-test/extra/rpl_tests/rpl_max_relay_size.test b/mysql-test/extra/rpl_tests/rpl_max_relay_size.test index 6b84cf67d58..5b546bbd891 100644 --- a/mysql-test/extra/rpl_tests/rpl_max_relay_size.test +++ b/mysql-test/extra/rpl_tests/rpl_max_relay_size.test @@ -43,7 +43,7 @@ set global max_relay_log_size=8192-1; # mapped to 4096 select @@global.max_relay_log_size; start slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; --echo # --echo # Test 2 @@ -55,7 +55,7 @@ set global max_relay_log_size=(5*4096); query_vertical select @@global.max_relay_log_size; start slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; --echo # --echo # Test 3: max_relay_log_size = 0 @@ -67,7 +67,7 @@ set global max_relay_log_size=0; query_vertical select @@global.max_relay_log_size; start slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; --echo # --echo # Test 4: Tests below are mainly to ensure that we have not coded with wrong assumptions @@ -78,7 +78,7 @@ reset slave; # test of relay log rotation when the slave is stopped # (to make sure it does not crash). flush logs; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; --echo # --echo # Test 5 @@ -96,7 +96,7 @@ create table t1 (a int); save_master_pos; connection slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; --echo # --echo # Test 6: one more rotation, to be sure Relay_Log_Space is correctly updated @@ -108,13 +108,12 @@ drop table t1; save_master_pos; connection slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; connection master; # test that the absence of relay logs does not make a master crash flush logs; --- replace_column 3 <Binlog_Ignore_DB> -query_vertical show master status; +source include/show_master_status.inc; # Restore max_binlog_size connection slave; diff --git a/mysql-test/extra/rpl_tests/rpl_reset_slave.test b/mysql-test/extra/rpl_tests/rpl_reset_slave.test index 83b39d3299a..2cc041a35e1 100644 --- a/mysql-test/extra/rpl_tests/rpl_reset_slave.test +++ b/mysql-test/extra/rpl_tests/rpl_reset_slave.test @@ -13,18 +13,18 @@ connection master; save_master_pos; connection slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; stop slave; change master to master_user='test'; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; reset slave; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; start slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; # test of crash with temp tables & RESET SLAVE # (test to see if RESET SLAVE clears temp tables in memory and disk) diff --git a/mysql-test/extra/rpl_tests/rpl_row_basic.test b/mysql-test/extra/rpl_tests/rpl_row_basic.test index c35a53f15bc..48ddbaf244a 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_basic.test +++ b/mysql-test/extra/rpl_tests/rpl_row_basic.test @@ -174,11 +174,18 @@ sync_slave_with_master; INSERT INTO t7 VALUES (1,3), (2,6), (3,9); SELECT * FROM t7 ORDER BY C1; +# since bug#31552/31609 idempotency is not default any longer. In order +# the preceeding test INSERT INTO t7 to pass the mode is switched +# temprorarily +set @@global.slave_exec_mode= 'IDEMPOTENT'; + connection master; --echo --- on master: new values inserted --- INSERT INTO t7 VALUES (1,2), (2,4), (3,6); SELECT * FROM t7 ORDER BY C1; sync_slave_with_master; + +set @@global.slave_exec_mode= default; --echo --- on slave: old values should be overwritten by replicated values --- SELECT * FROM t7 ORDER BY C1; @@ -206,12 +213,19 @@ SELECT * FROM t8 ORDER BY a; INSERT INTO t8 VALUES (1,2,3), (2,4,6), (3,6,9); SELECT * FROM t8 ORDER BY a; +# since bug#31552/31609 idempotency is not default any longer. In order +# the preceeding test INSERT INTO t8 to pass the mode is switched +# temprorarily +set @@global.slave_exec_mode= 'IDEMPOTENT'; + connection master; --echo --- on master --- # We insert a row that will cause conflict on the primary key but not # on the other keys. INSERT INTO t8 VALUES (2,4,8); sync_slave_with_master; +set @@global.slave_exec_mode= default; + --echo --- on slave --- SELECT * FROM t8 ORDER BY a; @@ -234,12 +248,17 @@ connection master; INSERT INTO t1 VALUES ('K','K'), ('L','L'), ('M','M'); --echo **** On Master **** sync_slave_with_master; +# since bug#31552/31609 idempotency is not default any longer. In order +# the following test DELETE FROM t1 to pass the mode is switched +# temprorarily +set @@global.slave_exec_mode= 'IDEMPOTENT'; DELETE FROM t1 WHERE C1 = 'L'; connection master; DELETE FROM t1; query_vertical SELECT COUNT(*) FROM t1 ORDER BY c1,c2; sync_slave_with_master; +set @@global.slave_exec_mode= default; let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); disable_query_log; eval SELECT "$last_error" AS Last_SQL_Error; diff --git a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test index 23ac16d24ae..b5795cf525d 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test +++ b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test @@ -69,6 +69,11 @@ ALTER TABLE t8 ADD e1 INT NOT NULL DEFAULT 0, ADD e2 INT NOT NULL DEFAULT 0, # Insert some values for tables on slave side. These should not be # modified when the row from the master is applied. +# since bug#31552/31609 idempotency is not default any longer. In order +# the following INSERTs to pass the mode is switched temprorarily +set @@global.slave_exec_mode= 'IDEMPOTENT'; + +# so the inserts are going to be overriden INSERT INTO t1_int VALUES (2, 4, 4711); INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar'); INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01'); @@ -86,6 +91,8 @@ SELECT * FROM t1_bit ORDER BY a; SELECT * FROM t1_char ORDER BY a; --echo **** On Slave **** sync_slave_with_master; +set @@global.slave_exec_mode= default; + SELECT a,b,x FROM t1_int ORDER BY a; SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit ORDER BY a; SELECT a,b,x FROM t1_char ORDER BY a; @@ -115,7 +122,7 @@ INSERT INTO t1_nodef VALUES (1,2); connection slave; --source include/wait_for_slave_sql_to_stop.inc --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 4 # 7 # 8 # 9 # 20 <Last_Error> 22 # 23 # 33 # 36 <Last_IO_Error> 38 <Last_SQL_Error> --query_vertical SHOW SLAVE STATUS SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -135,7 +142,7 @@ sync_slave_with_master; --echo **** On Slave **** SELECT * FROM t2; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 4 # 7 # 8 # 9 # 20 <Last_Error> 22 # 23 # 33 # 36 <Last_IO_Error> 38 <Last_SQL_Error> --query_vertical SHOW SLAVE STATUS connection master; @@ -147,7 +154,7 @@ INSERT INTO t4 VALUES (4); connection slave; --source include/wait_for_slave_sql_to_stop.inc --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 4 # 7 # 8 # 9 # 20 <Last_Error> 22 # 23 # 33 # 36 <Last_IO_Error> 38 <Last_SQL_Error> --query_vertical SHOW SLAVE STATUS SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -161,7 +168,7 @@ INSERT INTO t5 VALUES (5,10,25); connection slave; --source include/wait_for_slave_sql_to_stop.inc --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 4 # 7 # 8 # 9 # 20 <Last_Error> 22 # 23 # 33 # 36 <Last_IO_Error> 38 <Last_SQL_Error> --query_vertical SHOW SLAVE STATUS SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -175,7 +182,7 @@ INSERT INTO t6 VALUES (6,12,36); connection slave; --source include/wait_for_slave_sql_to_stop.inc --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 4 # 7 # 8 # 9 # 20 <Last_Error> 22 # 23 # 33 # 36 <Last_IO_Error> 38 <Last_SQL_Error> --query_vertical SHOW SLAVE STATUS SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -184,7 +191,7 @@ connection master; INSERT INTO t9 VALUES (6); sync_slave_with_master; --replace_result $SLAVE_MYPORT SLAVE_PORT ---replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 4 # 7 # 8 # 9 # 20 <Last_Error> 22 # 23 # 33 # 36 <Last_IO_Error> 38 <Last_SQL_Error> --query_vertical SHOW SLAVE STATUS # Testing some tables extra field that can be null and cannot be null diff --git a/mysql-test/include/delete_anonymous_users.inc b/mysql-test/include/delete_anonymous_users.inc index 9f642223748..704e74ae4a3 100644 --- a/mysql-test/include/delete_anonymous_users.inc +++ b/mysql-test/include/delete_anonymous_users.inc @@ -1,5 +1,7 @@ # Remove anonymous users added by add_anonymous_users.inc +disable_warnings; disable_query_log; DELETE FROM mysql.user where host='localhost' and user=''; FLUSH PRIVILEGES; enable_query_log; +enable_warnings; diff --git a/mysql-test/include/have_binlog_format_row_or_statement.inc b/mysql-test/include/have_binlog_format_row_or_statement.inc new file mode 100644 index 00000000000..c89df82eb80 --- /dev/null +++ b/mysql-test/include/have_binlog_format_row_or_statement.inc @@ -0,0 +1,7 @@ +--source include/have_log_bin.inc + +-- require r/have_binlog_format_statement.require +--disable_query_log +--replace_result ROW STATEMENT +show variables like "binlog_format"; +--enable_query_log diff --git a/mysql-test/include/have_innodb.inc b/mysql-test/include/have_innodb.inc index cbffe6a2574..8944cc46f3e 100644 --- a/mysql-test/include/have_innodb.inc +++ b/mysql-test/include/have_innodb.inc @@ -1,4 +1,4 @@ disable_query_log; --require r/true.require -select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'innodb'; +select (support = 'YES' or support = 'DEFAULT' or support = 'ENABLED') as `TRUE` from information_schema.engines where engine = 'innodb'; enable_query_log; diff --git a/mysql-test/include/have_local_infile.inc b/mysql-test/include/have_local_infile.inc new file mode 100644 index 00000000000..4a1362c6e30 --- /dev/null +++ b/mysql-test/include/have_local_infile.inc @@ -0,0 +1,4 @@ +--require r/have_local_infile.require +disable_query_log; +show variables like 'local_infile'; +enable_query_log; diff --git a/mysql-test/include/have_multi_ndb.inc b/mysql-test/include/have_multi_ndb.inc index 9779f181191..8dbfa2aa034 100644 --- a/mysql-test/include/have_multi_ndb.inc +++ b/mysql-test/include/have_multi_ndb.inc @@ -4,18 +4,26 @@ connect (server2,127.0.0.1,root,,test,$MASTER_MYPORT1,); # Check that server1 has NDB support connection server1; +let $engines_table= query_get_value(SHOW TABLES FROM information_schema LIKE 'ENGINES', Tables_in_information_schema (ENGINES), 1); disable_query_log; +if (`SELECT 1 FROM dual WHERE '$engines_table' = 'engines'`) +{ --require r/true.require -select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'ndbcluster'; +SELECT (support = 'YES' or support = 'DEFAULT' or support = 'ENABLED') as `TRUE` FROM information_schema.engines WHERE engine = 'ndbcluster'; --source include/ndb_not_readonly.inc +} enable_query_log; # Check that server2 has NDB support connection server2; +let $engines_table= query_get_value(SHOW TABLES FROM information_schema LIKE 'ENGINES', Tables_in_information_schema (ENGINES), 1); disable_query_log; +if (`SELECT 1 FROM dual WHERE '$engines_table' = 'engines'`) +{ --require r/true.require -select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'ndbcluster'; +SELECT (support = 'YES' or support = 'DEFAULT' or support = 'ENABLED') as `TRUE` FROM information_schema.engines WHERE engine = 'ndbcluster'; --source include/ndb_not_readonly.inc +} enable_query_log; # cleanup diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc index 3005e67935b..703dfa44df0 100644 --- a/mysql-test/include/mix1.inc +++ b/mysql-test/include/mix1.inc @@ -723,20 +723,6 @@ set @@sort_buffer_size=default; DROP TABLE t1,t2; -# -# Bug #32815: query with ORDER BY and a possible ref_or_null access -# - -CREATE TABLE t1 (id int, type char(6), d int, INDEX idx(id,d)) ENGINE=InnoDB; -INSERT INTO t1 VALUES - (191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2); - -EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; -SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; - -DROP TABLE t1; - - # Test of behaviour with CREATE ... SELECT # @@ -1091,6 +1077,19 @@ desc t1; show create table t1; drop table t1; +# +# Bug #32815: query with ORDER BY and a possible ref_or_null access +# + +CREATE TABLE t1 (id int, type char(6), d int, INDEX idx(id,d)) ENGINE=InnoDB; +INSERT INTO t1 VALUES + (191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2); + +EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; +SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; + +DROP TABLE t1; + --echo End of 5.0 tests # Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY @@ -1383,4 +1382,32 @@ create table t1 (a int auto_increment primary key) engine=innodb; alter table t1 order by a; drop table t1; +# +# Bug #33697: ORDER BY primary key DESC vs. ref access + filesort +# (reproduced only with InnoDB tables) +# + +CREATE TABLE t1 + (vid integer NOT NULL, + tid integer NOT NULL, + idx integer NOT NULL, + name varchar(128) NOT NULL, + type varchar(128) NULL, + PRIMARY KEY(idx, vid, tid), + UNIQUE(vid, tid, name) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES + (1,1,1,'pk',NULL),(2,1,1,'pk',NULL),(3,1,1,'pk',NULL),(4,1,1,'c1',NULL), + (5,1,1,'pk',NULL),(1,1,2,'c1',NULL),(2,1,2,'c1',NULL),(3,1,2,'c1',NULL), + (4,1,2,'c2',NULL),(5,1,2,'c1',NULL),(2,1,3,'c2',NULL),(3,1,3,'c2',NULL), + (4,1,3,'pk',NULL),(5,1,3,'c2',NULL), + (2,1,4,'c_extra',NULL),(3,1,4,'c_extra',NULL); + +EXPLAIN SELECT * FROM t1 WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; + +SELECT * FROM t1 WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/include/ps_modify.inc b/mysql-test/include/ps_modify.inc index f66f888261d..4cde18b97d1 100644 --- a/mysql-test/include/ps_modify.inc +++ b/mysql-test/include/ps_modify.inc @@ -108,6 +108,7 @@ execute stmt1 using @arg00, @arg01; select a,b from t1 where a=@arg00; set @arg00=NULL; set @arg01=2; +--error 1048 execute stmt1 using @arg00, @arg01; select a,b from t1 order by a; set @arg00=0; diff --git a/mysql-test/include/set_binlog_format_mixed.sql b/mysql-test/include/set_binlog_format_mixed.sql new file mode 100644 index 00000000000..836992d1080 --- /dev/null +++ b/mysql-test/include/set_binlog_format_mixed.sql @@ -0,0 +1,2 @@ +SET GLOBAL BINLOG_FORMAT=MIXED; +SET SESSION BINLOG_FORMAT=MIXED; diff --git a/mysql-test/include/set_binlog_format_row.sql b/mysql-test/include/set_binlog_format_row.sql new file mode 100644 index 00000000000..49f34c8ccd1 --- /dev/null +++ b/mysql-test/include/set_binlog_format_row.sql @@ -0,0 +1,2 @@ +SET GLOBAL BINLOG_FORMAT=ROW; +SET SESSION BINLOG_FORMAT=ROW; diff --git a/mysql-test/include/set_binlog_format_statement.sql b/mysql-test/include/set_binlog_format_statement.sql new file mode 100644 index 00000000000..ed286e7e3cc --- /dev/null +++ b/mysql-test/include/set_binlog_format_statement.sql @@ -0,0 +1,2 @@ +SET GLOBAL BINLOG_FORMAT=STATEMENT; +SET SESSION BINLOG_FORMAT=STATEMENT; diff --git a/mysql-test/include/show_binary_logs.inc b/mysql-test/include/show_binary_logs.inc new file mode 100644 index 00000000000..c3729a8f9b9 --- /dev/null +++ b/mysql-test/include/show_binary_logs.inc @@ -0,0 +1,5 @@ +# show binary logs + +# mask out the binlog position +-- replace_column 2 # +show binary logs; diff --git a/mysql-test/include/show_binlog_events.inc b/mysql-test/include/show_binlog_events.inc index 7377b4a0fed..fcdf84102aa 100644 --- a/mysql-test/include/show_binlog_events.inc +++ b/mysql-test/include/show_binlog_events.inc @@ -1,5 +1,5 @@ --let $binlog_start=106 --replace_result $binlog_start <binlog_start> --replace_column 2 # 4 # 5 # ---replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /file_id=[0-9]+/file_id=#/ --eval show binlog events from $binlog_start diff --git a/mysql-test/include/show_binlog_events2.inc b/mysql-test/include/show_binlog_events2.inc index 234b7e06fcf..5dd272c562d 100644 --- a/mysql-test/include/show_binlog_events2.inc +++ b/mysql-test/include/show_binlog_events2.inc @@ -1,7 +1,3 @@ -# -# Differs slightly from show_binlog events in showing server_id -# which is important for some tests -# --let $binlog_start=106 --replace_result $binlog_start <binlog_start> --replace_column 2 # 5 # diff --git a/mysql-test/include/show_master_logs.inc b/mysql-test/include/show_master_logs.inc new file mode 100644 index 00000000000..4792ebd9651 --- /dev/null +++ b/mysql-test/include/show_master_logs.inc @@ -0,0 +1,5 @@ +# show master logs + +# mask out the binlog position +-- replace_column 2 # +query_vertical show master logs; diff --git a/mysql-test/include/show_master_status.inc b/mysql-test/include/show_master_status.inc new file mode 100644 index 00000000000..b7b32a65df4 --- /dev/null +++ b/mysql-test/include/show_master_status.inc @@ -0,0 +1,5 @@ +# show master status + +# mask out the binlog position +-- replace_column 2 # 3 <Binlog_Do_DB> 4 <Binlog_Ignore_DB> +show master status; diff --git a/mysql-test/include/show_slave_status2.inc b/mysql-test/include/show_slave_status2.inc new file mode 100644 index 00000000000..9c4e14c62c2 --- /dev/null +++ b/mysql-test/include/show_slave_status2.inc @@ -0,0 +1,8 @@ +# Include file to show the slave status, masking out some information +# that varies depending on where the test is executed. + +# masked out log positions + +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 # +query_vertical SHOW SLAVE STATUS; diff --git a/mysql-test/lib/My/Config.pm b/mysql-test/lib/My/Config.pm new file mode 100644 index 00000000000..5491e341ddc --- /dev/null +++ b/mysql-test/lib/My/Config.pm @@ -0,0 +1,422 @@ +# -*- cperl -*- + +package My::Config::Option; + +use strict; +use warnings; + + +sub new { + my ($class, $option_name, $option_value)= @_; + my $self= bless { name => $option_name, + value => $option_value + }, $class; + return $self; +} + + +sub name { + my ($self)= @_; + return $self->{name}; +} + + +sub value { + my ($self)= @_; + return $self->{value}; +} + + +package My::Config::Group; + +use strict; +use warnings; + + +sub new { + my ($class, $group_name)= @_; + my $self= bless { name => $group_name, + options => [], + options_by_name => {}, + }, $class; + return $self; +} + + +sub insert { + my ($self, $option_name, $value, $if_not_exist)= @_; + my $option= $self->option($option_name); + if (defined($option) and !$if_not_exist) { + $option->{value}= $value; + } + else { + my $option= My::Config::Option->new($option_name, $value); + # Insert option in list + push(@{$self->{options}}, $option); + # Insert option in hash + $self->{options_by_name}->{$option_name}= $option; + } + return $option; +} + +sub remove { + my ($self, $option_name)= @_; + + # Check that option exists + my $option= $self->option($option_name); + + return undef unless defined $option; + + # Remove from the hash + delete($self->{options_by_name}->{$option_name}) or die; + + # Remove from the array + @{$self->{options}}= grep { $_->name ne $option_name } @{$self->{options}}; + + return $option; +} + + +sub options { + my ($self)= @_; + return @{$self->{options}}; +} + + +sub name { + my ($self)= @_; + return $self->{name}; +} + + +# +# Return a specific option in the group +# +sub option { + my ($self, $option_name)= @_; + + return $self->{options_by_name}->{$option_name}; +} + + +# +# Return a specific value for an option in the group +# +sub value { + my ($self, $option_name)= @_; + my $option= $self->option($option_name); + + die "No option named '$option_name' in this group" + if ! defined($option); + + return $option->value(); +} + + +package My::Config; + +use strict; +use warnings; +use IO::File; +use File::Basename; + +# +# Constructor for My::Config +# - represents a my.cnf config file +# +# Array of arrays +# +sub new { + my ($class, $path)= @_; + my $group_name= undef; + + my $self= bless { groups => [] }, $class; + my $F= IO::File->new($path, "<") + or die "Could not open '$path': $!"; + + while ( my $line= <$F> ) { + chomp($line); + + # [group] + if ( $line =~ /\[(.*)\]/ ) { + # New group found + $group_name= $1; + #print "group: $group_name\n"; + + $self->insert($group_name, undef, undef); + } + + # Magic #! comments + elsif ( $line =~ /^#\!/) { + my $magic= $line; + die "Found magic comment '$magic' outside of group" + unless $group_name; + + #print "$magic\n"; + $self->insert($group_name, $magic, undef); + } + + # Comments + elsif ( $line =~ /^#/ || $line =~ /^;/) { + # Skip comment + next; + } + + # Empty lines + elsif ( $line =~ /^$/ ) { + # Skip empty lines + next; + } + + # !include <filename> + elsif ( $line =~ /^\!include\s*(.*?)\s*$/ ) { + my $include_file_name= dirname($path)."/".$1; + # Check that the file exists + die "The include file '$include_file_name' does not exist" + unless -f $include_file_name; + + $self->append(My::Config->new($include_file_name)); + } + + # <option> + elsif ( $line =~ /^([\@\w-]+)\s*$/ ) { + my $option= $1; + + die "Found option '$option' outside of group" + unless $group_name; + + #print "$option\n"; + $self->insert($group_name, $option, undef); + } + + # <option>=<value> + elsif ( $line =~ /^([\@\w-]+)\s*=\s*(.*?)\s*$/ ) { + my $option= $1; + my $value= $2; + + die "Found option '$option=$value' outside of group" + unless $group_name; + + #print "$option=$value\n"; + $self->insert($group_name, $option, $value); + } else { + die "Unexpected line '$line' found in '$path'"; + } + + } + undef $F; # Close the file + + return $self; +} + +# +# Insert a new group if it does not already exist +# and add option if defined +# +sub insert { + my ($self, $group_name, $option, $value, $if_not_exist)= @_; + my $group; + + # Create empty array for the group if it doesn't exist + if ( !$self->group_exists($group_name) ) { + $group= $self->_group_insert($group_name); + } + else { + $group= $self->group($group_name); + } + + if ( defined $option ) { + #print "option: $option, value: $value\n"; + + # Add the option to the group + $group->insert($option, $value, $if_not_exist); + } +} + +# +# Remove a option, given group and option name +# +sub remove { + my ($self, $group_name, $option_name)= @_; + my $group= $self->group($group_name); + + die "group '$group_name' does not exist" + unless defined($group); + + $group->remove($option_name) or + die "option '$option_name' does not exist"; +} + + + +# +# Check if group with given name exists in config +# +sub group_exists { + my ($self, $group_name)= @_; + + foreach my $group ($self->groups()) { + return 1 if $group->{name} eq $group_name; + } + return 0; +} + + +# +# Insert a new group into config +# +sub _group_insert { + my ($self, $group_name)= @_; + caller eq __PACKAGE__ or die; + + # Check that group does not already exist + die "Group already exists" if $self->group_exists($group_name); + + my $group= My::Config::Group->new($group_name); + push(@{$self->{groups}}, $group); + return $group; +} + + +# +# Append a configuration to current config +# +sub append { + my ($self, $from)= @_; + + foreach my $group ($from->groups()) { + foreach my $option ($group->options()) { + $self->insert($group->name(), $option->name(), $option->value()); + } + + } +} + + +# +# Return a list with all the groups in config +# +sub groups { + my ($self)= @_; + return ( @{$self->{groups}} ); +} + + +# +# Return a list of all the groups in config +# starting with the given string +# +sub like { + my ($self, $prefix)= @_; + return ( grep ( $_->{name} =~ /^$prefix/, $self->groups()) ); +} + + +# +# Return the first group in config +# starting with the given string +# +sub first_like { + my ($self, $prefix)= @_; + return ($self->like($prefix))[0]; +} + + +# +# Return a specific group in the config +# +sub group { + my ($self, $group_name)= @_; + + foreach my $group ( $self->groups() ) { + return $group if $group->{name} eq $group_name; + } + return undef; +} + + +# +# Return a list of all options in a specific group in the config +# +sub options_in_group { + my ($self, $group_name)= @_; + + my $group= $self->group($group_name); + return () unless defined $group; + return $group->options(); +} + + +# +# Return a value given group and option name +# +sub value { + my ($self, $group_name, $option_name)= @_; + my $group= $self->group($group_name); + + die "group '$group_name' does not exist" + unless defined($group); + + my $option= $group->option($option_name); + die "option '$option_name' does not exist" + unless defined($option); + + return $option->value(); +} + + +# +# Check if an option exists +# +sub exists { + my ($self, $group_name, $option_name)= @_; + my $group= $self->group($group_name); + + die "group '$group_name' does not exist" + unless defined($group); + + my $option= $group->option($option_name); + return defined($option); +} + + +# Overload "to string"-operator with 'stringify' +use overload + '""' => \&stringify; + +# +# Return the config as a string in my.cnf file format +# +sub stringify { + my ($self)= @_; + my $res; + + foreach my $group ($self->groups()) { + $res .= "[$group->{name}]\n"; + + foreach my $option ($group->options()) { + $res .= $option->name(); + my $value= $option->value(); + if (defined $value) { + $res .= "=$value"; + } + $res .= "\n"; + } + $res .= "\n"; + } + return $res; +} + + +# +# Save the config to named file +# +sub save { + my ($self, $path)= @_; + my $F= IO::File->new($path, ">") + or die "Could not open '$path': $!"; + print $F $self; + undef $F; # Close the file +} + +1; diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index 0d705104303..d9ba9466482 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -22,8 +22,10 @@ use File::Basename; use IO::File(); use strict; +use My::Config; + sub collect_test_cases ($); -sub collect_one_suite ($$); +sub collect_one_suite ($); sub collect_one_test_case ($$$$$$$$$); sub mtr_options_from_test_file($$); @@ -61,7 +63,7 @@ sub collect_test_cases ($) { foreach my $suite (split(",", $suites)) { - collect_one_suite($suite, $cases); + push(@$cases, collect_one_suite($suite)); } @@ -205,51 +207,24 @@ sub split_testname { } -sub collect_one_suite($$) +sub collect_one_suite($) { my $suite= shift; # Test suite name - my $cases= shift; # List of test cases + my @cases; # Array of hash mtr_verbose("Collecting: $suite"); - my $combination_file= "combinations"; - my $combinations = []; - my $suitedir= "$::glob_mysql_test_dir"; # Default - my $combination_file= "$::glob_mysql_test_dir/$combination_file"; if ( $suite ne "main" ) { $suitedir= mtr_path_exists("$suitedir/suite/$suite", "$suitedir/$suite"); mtr_verbose("suitedir: $suitedir"); - $combination_file= "$suitedir/$combination_file"; } my $testdir= "$suitedir/t"; my $resdir= "$suitedir/r"; - if (!@::opt_combination) - { - # Read combinations file - if ( open(COMB,$combination_file) ) - { - while (<COMB>) - { - chomp; - s/\ +/ /g; - push (@$combinations, $_) unless ($_ eq ''); - } - close COMB; - } - } - else - { - # take the combination from command-line - @$combinations = @::opt_combination; - } - # Remember last element position - my $begin_index = $#{@$cases} + 1; - # ---------------------------------------------------------------------- # Build a hash of disabled testcases for this suite # ---------------------------------------------------------------------- @@ -324,7 +299,7 @@ sub collect_one_suite($$) } collect_one_test_case($testdir,$resdir,$suite,$tname, - "$tname.$extension",$cases,\%disabled, + "$tname.$extension",\@cases,\%disabled, $component_id,$suite_opts); } } @@ -354,85 +329,168 @@ sub collect_one_suite($$) next if ($do_test and not $tname =~ /$do_test/o); collect_one_test_case($testdir,$resdir,$suite,$tname, - $elem,$cases,\%disabled,$component_id, + $elem,\@cases,\%disabled,$component_id, $suite_opts); } closedir TESTDIR; } + + # Return empty list if no testcases found + return if (@cases == 0); + # ---------------------------------------------------------------------- - # Proccess combinations only if new tests were added + # Read combinations for this suite and build testcases x combinations + # if any combinations exists # ---------------------------------------------------------------------- - if (0 and $combinations && $begin_index <= $#{@$cases}) - { - my $end_index = $#{@$cases}; - my $is_copy; - # Keep original master/slave options - my @orig_opts; - for (my $idx = $begin_index; $idx <= $end_index; $idx++) - { - foreach my $param (('master_opt','slave_opt','slave_mi')) - { - @{$orig_opts[$idx]{$param}} = @{$cases->[$idx]->{$param}}; + if ( ! $::opt_skip_combination ) + { + my @combinations; + my $combination_file= "$suitedir/combinations"; + #print "combination_file: $combination_file\n"; + if (@::opt_combinations) + { + # take the combination from command-line + mtr_verbose("Take the combination from command line"); + foreach my $combination (@::opt_combinations) { + my $comb= {}; + $comb->{name}= $combination; + push(@{$comb->{comb_opt}}, $combination); + push(@combinations, $comb); + } + } + elsif (-f $combination_file ) + { + # Read combinations file in my.cnf format + mtr_verbose("Read combinations file"); + my $config= My::Config->new($combination_file); + + foreach my $group ($config->groups()) { + my $comb= {}; + $comb->{name}= $group->name(); + foreach my $option ( $group->options() ) { + push(@{$comb->{comb_opt}}, $option->name()."=".$option->value()); + } + push(@combinations, $comb); } } - my $comb_index = 1; - # Copy original test cases - foreach my $comb_set (@$combinations) - { - for (my $idx = $begin_index; $idx <= $end_index; $idx++) + + if (@combinations) + { + print " - adding combinations\n"; + #print_testcases(@cases); + + my @new_cases; + foreach my $comb (@combinations) { - my $test = $cases->[$idx]; - my $copied_test = {}; - foreach my $param (keys %{$test}) - { - # Scalar. Copy as is. - $copied_test->{$param} = $test->{$param}; - # Array. Copy reference instead itself - if ($param =~ /(master_opt|slave_opt|slave_mi)/) - { - my $new_arr = []; - @$new_arr = @{$orig_opts[$idx]{$param}}; - $copied_test->{$param} = $new_arr; - } - elsif ($param =~ /(comment|combinations)/) - { - $copied_test->{$param} = ''; - } - } - if ($is_copy) - { - push(@$cases, $copied_test); - $test = $cases->[$#{@$cases}]; - } - foreach my $comb_opt (split(/ /,$comb_set)) - { - push(@{$test->{'master_opt'}},$comb_opt); - push(@{$test->{'slave_opt'}},$comb_opt); - # Enable rpl if added option is --binlog-format and test case supports that - if ($comb_opt =~ /^--binlog-format=.+$/) - { - my @opt_pairs = split(/=/, $comb_opt); - if ($test->{'binlog_format'} =~ /^$opt_pairs[1]$/ || $test->{'binlog_format'} eq '') - { - $test->{'skip'} = 0; - $test->{'comment'} = ''; - } - else - { - $test->{'skip'} = 1; - $test->{'comment'} = "Requiring binlog format '$test->{'binlog_format'}'";; - } - } - } - $test->{'combination'} = $comb_set; - } - $is_copy = 1; - $comb_index++; - } + foreach my $test (@cases) + { + #print $test->{name}, " ", $comb, "\n"; + my $new_test= {}; + + while (my ($key, $value) = each(%$test)) { + if (ref $value eq "ARRAY") { + push(@{$new_test->{$key}}, @$value); + } else { + $new_test->{$key}= $value; + } + } + + # Append the combination options to master_opt and slave_opt + push(@{$new_test->{master_opt}}, @{$comb->{comb_opt}}); + push(@{$new_test->{slave_opt}}, @{$comb->{comb_opt}}); + + # Add combination name shrt name + $new_test->{combination}= $comb->{name}; + + # Add the new test to new test cases list + push(@new_cases, $new_test); + } + } + #print_testcases(@new_cases); + @cases= @new_cases; + #print_testcases(@cases); + } } - return $cases; + optimize_cases(\@cases); + #print_testcases(@cases); + + return @cases; +} + + +# +# Loop through all test cases +# - optimize which test to run by skipping unnecessary ones +# - update settings if necessary +# +sub optimize_cases { + my ($cases)= @_; + + foreach my $tinfo ( @$cases ) + { + # Skip processing if already marked as skipped + next if $tinfo->{skip}; + + # Replication test needs an adjustment of binlog format + if (mtr_match_prefix($tinfo->{'name'}, "rpl")) + { + + # ======================================================= + # Get binlog-format used by this test from master_opt + # ======================================================= + my $test_binlog_format; + foreach my $opt ( @{$tinfo->{master_opt}} ) { + $test_binlog_format= $test_binlog_format || + mtr_match_prefix($opt, "--binlog-format="); + } + # print $tinfo->{name}." uses ".$test_binlog_format."\n"; + + # ======================================================= + # If a special binlog format was selected with + # --mysqld=--binlog-format=x, skip all test with different + # binlog-format + # ======================================================= + if (defined $::used_binlog_format and + $test_binlog_format and + $::used_binlog_format ne $test_binlog_format) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Requires --binlog-format='$test_binlog_format'"; + next; + } + + # ======================================================= + # Check that testcase supports the designated binlog-format + # ======================================================= + if ($test_binlog_format and defined $tinfo->{'sup_binlog_formats'} ) + { + my $supported= + grep { $_ eq $test_binlog_format } @{$tinfo->{'sup_binlog_formats'}}; + if ( !$supported ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= + "Doesn't support --binlog-format='$test_binlog_format'"; + next; + } + } + + # ======================================================= + # Use dynamic switching of binlog-format if mtr started + # w/o --mysqld=--binlog-format=xxx and combinations. + # ======================================================= + if (!defined $tinfo->{'combination'} and + !defined $::used_binlog_format) + { + $test_binlog_format= $tinfo->{'sup_binlog_formats'}->[0]; + } + + # Save binlog format for dynamic switching + $tinfo->{binlog_format}= $test_binlog_format; + } + } } @@ -522,6 +580,7 @@ sub collect_one_test_case($$$$$$$$$) { $tinfo->{'slave_opt'}= []; $tinfo->{'slave_mi'}= []; + # Add suite opts foreach my $opt ( @$suite_opts ) { @@ -735,14 +794,6 @@ sub collect_one_test_case($$$$$$$$$) { return; } - if ( defined $tinfo->{'binlog_format'} and - ! ( $tinfo->{'binlog_format'} eq $::used_binlog_format ) ) - { - $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "Requiring binlog format '$tinfo->{'binlog_format'}'"; - return; - } - if ( $tinfo->{'need_debug'} && ! $::debug_compiled_binaries ) { $tinfo->{'skip'}= 1; @@ -822,10 +873,17 @@ sub collect_one_test_case($$$$$$$$$) { our @tags= ( ["include/have_innodb.inc", "innodb_test", 1], - ["include/have_binlog_format_row.inc", "binlog_format", "row"], + ["include/have_binlog_format_row.inc", "sup_binlog_formats", ["row"]], ["include/have_log_bin.inc", "need_binlog", 1], - ["include/have_binlog_format_statement.inc", "binlog_format", "statement"], - ["include/have_binlog_format_mixed.inc", "binlog_format", "mixed"], + ["include/have_binlog_format_statement.inc", + "sup_binlog_formats", ["statement"]], + ["include/have_binlog_format_mixed.inc", "sup_binlog_formats", ["mixed"]], + ["include/have_binlog_format_mixed_or_row.inc", + "sup_binlog_formats", ["mixed","row"]], + ["include/have_binlog_format_mixed_or_statement.inc", + "sup_binlog_formats", ["mixed","statement"]], + ["include/have_binlog_format_row_or_statement.inc", + "sup_binlog_formats", ["row","statement"]], ["include/big_test.inc", "big_test", 1], ["include/have_debug.inc", "need_debug", 1], ["include/have_ndb.inc", "ndb_test", 1], @@ -851,8 +909,8 @@ sub mtr_options_from_test_file($$) { { if ( index($line, $tag->[0]) >= 0 ) { - # Tag matched, assign value to "tinfo" - $tinfo->{"$tag->[1]"}= $tag->[2]; + # Tag matched, assign value to "tinfo" + $tinfo->{"$tag->[1]"}= $tag->[2]; } } @@ -873,8 +931,29 @@ sub mtr_options_from_test_file($$) { mtr_options_from_test_file($tinfo, $sourced_file); } } + } +} + +sub print_testcases { + my (@cases)= @_; + + print "=" x 60, "\n"; + foreach my $test (@cases){ + print "[", $test->{name}, "]", "\n"; + while ((my ($key, $value)) = each(%$test)) { + print " ", $key, "="; + if (ref $value eq "ARRAY") { + print join(", ", @$value); + } else { + print $value; + } + print "\n"; + } + print "\n"; } + print "=" x 60, "\n"; } + 1; diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index 226f73a21de..0173e8b8572 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -280,4 +280,33 @@ sub mtr_cmp_opts ($$) { return 0; # They are the same } +# +# Compare two arrays and put all unequal elements into a new one +# +sub mtr_diff_opts ($$) { + my $l1= shift; + my $l2= shift; + my $f; + my $l= []; + foreach my $e1 (@$l1) + { + $f= undef; + foreach my $e2 (@$l2) + { + $f= 1 unless ($e1 ne $e2); + } + push(@$l, $e1) unless (defined $f); + } + foreach my $e2 (@$l2) + { + $f= undef; + foreach my $e1 (@$l1) + { + $f= 1 unless ($e1 ne $e2); + } + push(@$l, $e2) unless (defined $f); + } + return $l; +} + 1; diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index 657d84bb049..c8f3263e7e3 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -50,9 +50,13 @@ my $tot_real_time= 0; sub mtr_report_test_name ($) { my $tinfo= shift; + my $tname= $tinfo->{name}; - _mtr_log("$tinfo->{name}"); - printf "%-30s ", $tinfo->{'name'}; + $tname.= " '$tinfo->{combination}'" + if defined $tinfo->{combination}; + + _mtr_log($tname); + printf "%-30s ", $tname; } sub mtr_report_test_skipped ($) { @@ -365,6 +369,24 @@ sub mtr_report_stats ($) { /Slave: Can't DROP 'c7'.* 1091/ or /Slave: Key column 'c6'.* 1072/ or + # rpl_idempotency.test produces warnings for the slave. + ($testname eq 'rpl.rpl_idempotency' and + (/Slave: Can\'t find record in \'t1\' Error_code: 1032/ or + /Slave: Cannot add or update a child row: a foreign key constraint fails .* Error_code: 1452/ + )) or + + # These tests does "kill" on queries, causing sporadic errors when writing to logs + (($testname eq 'rpl.rpl_skip_error' or + $testname eq 'rpl.rpl_err_ignoredtable' or + $testname eq 'binlog.binlog_killed_simulate' or + $testname eq 'binlog.binlog_killed') and + (/Failed to write to mysql\.\w+_log/ + )) or + + # rpl_temporary has an error on slave that can be ignored + ($testname eq 'rpl.rpl_temporary' and + (/Slave: Can\'t find record in \'user\' Error_code: 1032/ + )) # maria-recovery.test has warning about missing log file /Can't get stat of '.*maria_log.00/ or # and about marked-corrupted table diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index cea37c5027a..ca15c80b83b 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -52,6 +52,9 @@ # "perl -d:Trace mysql-test-run.pl" # + +use lib "lib/"; + $Devel::Trace::TRACE= 0; # Don't trace boring init stuff #require 5.6.1; @@ -172,7 +175,8 @@ our $opt_bench= 0; our $opt_small_bench= 0; our $opt_big_test= 0; -our @opt_combination; +our @opt_combinations; +our $opt_skip_combination; our @opt_extra_mysqld_opt; our @opt_extra_mysqltest_opt; @@ -571,7 +575,8 @@ sub command_line_setup () { 'skip-im' => \$opt_skip_im, 'skip-test=s' => \$opt_skip_test, 'big-test' => \$opt_big_test, - 'combination=s' => \@opt_combination, + 'combination=s' => \@opt_combinations, + 'skip-combination' => \$opt_skip_combination, # Specify ports 'master_port=i' => \$opt_master_myport, @@ -849,20 +854,23 @@ sub command_line_setup () { # -------------------------------------------------------------------------- # Find out type of logging that are being used # -------------------------------------------------------------------------- - # NOTE if the default binlog format is changed, this has to be changed - $used_binlog_format= "statement"; if (!$opt_extern && $mysql_version_id >= 50100 ) { - $used_binlog_format= "mixed"; # Default value for binlog format - foreach my $arg ( @opt_extra_mysqld_opt ) { if ( $arg =~ /binlog[-_]format=(\S+)/ ) { - $used_binlog_format= $1; + $used_binlog_format= $1; } } - mtr_report("Using binlog format '$used_binlog_format'"); + if (defined $used_binlog_format) + { + mtr_report("Using binlog format '$used_binlog_format'"); + } + else + { + mtr_report("Using dynamic switching of binlog format"); + } } @@ -980,6 +988,10 @@ sub command_line_setup () { mtr_error("Will not run in record mode without a specific test case"); } + if ( $opt_record ) + { + $opt_skip_combination = 1; + } # -------------------------------------------------------------------------- # ps protcol flag @@ -3397,6 +3409,7 @@ sub run_testcase_check_skip_test($) sub do_before_run_mysqltest($) { my $tinfo= shift; + my $args; # Remove old files produced by mysqltest my $base_file= mtr_match_extension($tinfo->{'result_file'}, @@ -3417,6 +3430,28 @@ sub do_before_run_mysqltest($) # if script decided to run mysqltest cluster _is_ installed ok $ENV{'NDB_STATUS_OK'} = "YES"; } + if (defined $tinfo->{binlog_format} and $mysql_version_id > 50100 ) + { + # Dynamically switch binlog format of + # master, slave is always restarted + foreach my $server ( @$master ) + { + next unless ($server->{'pid'}); + + mtr_init_args(\$args); + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--user=root"); + mtr_add_arg($args, "--port=$server->{'port'}"); + mtr_add_arg($args, "--socket=$server->{'path_sock'}"); + + my $sql= "include/set_binlog_format_".$tinfo->{binlog_format}.".sql"; + mtr_verbose("Setting binlog format:", $tinfo->{binlog_format}); + if (mtr_run($exe_mysql, $args, $sql, "", "", "") != 0) + { + mtr_error("Failed to switch binlog format"); + } + } + } } } @@ -3857,6 +3892,14 @@ sub mysqld_arguments ($$$$) { mtr_add_arg($args, "%s--user=root"); } + # When mysqld is run by a root user(euid is 0), it will fail + # to start unless we specify what user to run as, see BUG#30630 + my $euid= $>; + if (!$glob_win32 and $euid == 0 and + (grep(/^--user/, @$extra_opt, @opt_extra_mysqld_opt)) == 0) { + mtr_add_arg($args, "%s--user=root", $prefix); + } + if ( $opt_valgrind_mysqld ) { mtr_add_arg($args, "%s--skip-safemalloc", $prefix); @@ -3963,7 +4006,7 @@ sub mysqld_arguments ($$$$) { my $slave_load_path= "../tmp"; mtr_add_arg($args, "%s--slave-load-tmpdir=%s", $prefix, $slave_load_path); - mtr_add_arg($args, "%s--set-variable=slave_net_timeout=10", $prefix); + mtr_add_arg($args, "%s--set-variable=slave_net_timeout=120", $prefix); if ( @$slave_master_info ) { @@ -4316,10 +4359,19 @@ sub run_testcase_need_master_restart($) elsif (! mtr_same_opts($master->[0]->{'start_opts'}, $tinfo->{'master_opt'}) ) { - $do_restart= 1; - mtr_verbose("Restart master: running with different options '" . - join(" ", @{$tinfo->{'master_opt'}}) . "' != '" . - join(" ", @{$master->[0]->{'start_opts'}}) . "'" ); + # Chech that diff is binlog format only + my $diff_opts= mtr_diff_opts($master->[0]->{'start_opts'},$tinfo->{'master_opt'}); + if (scalar(@$diff_opts) eq 2) + { + $do_restart= 1 unless ($diff_opts->[0] =~/^--binlog-format=/ and $diff_opts->[1] =~/^--binlog-format=/); + } + else + { + $do_restart= 1; + mtr_verbose("Restart master: running with different options '" . + join(" ", @{$tinfo->{'master_opt'}}) . "' != '" . + join(" ", @{$master->[0]->{'start_opts'}}) . "'" ); + } } elsif( ! $master->[0]->{'pid'} ) { @@ -5238,8 +5290,9 @@ Options to control what test suites or cases to run skip-im Don't start IM, and skip the IM test cases big-test Set the environment variable BIG_TEST, which can be checked from test cases. - combination="ARG1 .. ARG2" Specify a set of "mysqld" arguments for one - combination. + combination="ARG1 .. ARG2" Specify a set of "mysqld" arguments for one + combination. + skip-combination Skip any combination options and combinations files Options that specify ports diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index 54c2df34a7f..bc9daf43f14 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -231,8 +231,7 @@ a b 204 7 delete from t1 where a=0; update t1 set a=NULL where b=6; -Warnings: -Warning 1048 Column 'a' cannot be null +ERROR 23000: Column 'a' cannot be null update t1 set a=300 where b=7; SET SQL_MODE=''; insert into t1(a,b)values(NULL,8); @@ -247,7 +246,7 @@ a b 1 1 200 2 201 4 -0 6 +203 6 300 7 301 8 400 9 @@ -263,6 +262,7 @@ a b 1 1 200 2 201 4 +203 6 300 7 301 8 400 9 @@ -273,20 +273,20 @@ a b 405 14 delete from t1 where a=0; update t1 set a=NULL where b=13; -Warnings: -Warning 1048 Column 'a' cannot be null +ERROR 23000: Column 'a' cannot be null update t1 set a=500 where b=14; select * from t1 order by b; a b 1 1 200 2 201 4 +203 6 300 7 301 8 400 9 401 10 402 11 -0 13 +404 13 500 14 drop table t1; create table t1 (a bigint); diff --git a/mysql-test/r/bdb_notembedded.result b/mysql-test/r/bdb_notembedded.result deleted file mode 100644 index 14cb5fad915..00000000000 --- a/mysql-test/r/bdb_notembedded.result +++ /dev/null @@ -1,35 +0,0 @@ -set autocommit=1; -reset master; -create table bug16206 (a int); -insert into bug16206 values(1); -start transaction; -insert into bug16206 values(2); -commit; -show binlog events; -Log_name Pos Event_type Server_id End_log_pos Info -f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4 -f n Query 1 n use `test`; create table bug16206 (a int) -f n Query 1 n use `test`; insert into bug16206 values(1) -f n Query 1 n use `test`; insert into bug16206 values(2) -drop table bug16206; -reset master; -create table bug16206 (a int) engine= bdb; -insert into bug16206 values(0); -insert into bug16206 values(1); -start transaction; -insert into bug16206 values(2); -commit; -insert into bug16206 values(3); -show binlog events; -Log_name Pos Event_type Server_id End_log_pos Info -f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4 -f n Query 1 n use `test`; create table bug16206 (a int) engine= bdb -f n Query 1 n use `test`; insert into bug16206 values(0) -f n Query 1 n use `test`; insert into bug16206 values(1) -f n Query 1 n use `test`; BEGIN -f n Query 1 n use `test`; insert into bug16206 values(2) -f n Query 1 n use `test`; COMMIT -f n Query 1 n use `test`; insert into bug16206 values(3) -drop table bug16206; -set autocommit=0; -End of 5.0 tests diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index d257e526abf..b5bfadf1f57 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -271,7 +271,7 @@ group_concat(distinct s1 order by s2) c,b,a select group_concat(distinct s1 order by s2) from t1; group_concat(distinct s1 order by s2) -c,b,a,c +c,b,a drop table t1; create table t1 (a int, c int); insert into t1 values (1, 2), (2, 3), (2, 4), (3, 5); @@ -876,4 +876,65 @@ select group_concat(f1) from t1; group_concat(f1) , drop table t1; +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1, 1), (2, 2), (2, 3); +SELECT GROUP_CONCAT(DISTINCT a ORDER BY b) FROM t1; +GROUP_CONCAT(DISTINCT a ORDER BY b) +1,2 +SELECT GROUP_CONCAT(DISTINCT a ORDER BY b DESC) FROM t1; +GROUP_CONCAT(DISTINCT a ORDER BY b DESC) +2,1 +SELECT GROUP_CONCAT(DISTINCT a) FROM t1; +GROUP_CONCAT(DISTINCT a) +1,2 +SELECT GROUP_CONCAT(DISTINCT a + 1 ORDER BY 3 - b) FROM t1; +GROUP_CONCAT(DISTINCT a + 1 ORDER BY 3 - b) +3,2 +SELECT GROUP_CONCAT(DISTINCT a + 1 ORDER BY b) FROM t1; +GROUP_CONCAT(DISTINCT a + 1 ORDER BY b) +2,3 +SELECT GROUP_CONCAT(a ORDER BY 3 - b) FROM t1; +GROUP_CONCAT(a ORDER BY 3 - b) +2,2,1 +CREATE TABLE t2 (a INT, b INT, c INT, d INT); +INSERT INTO t2 VALUES (1,1, 1,1), (1,1, 2,2), (1,2, 2,1), (2,1, 1,2); +SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY c, d) FROM t2; +GROUP_CONCAT(DISTINCT a, b ORDER BY c, d) +11,21,12 +SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY d, c) FROM t2; +GROUP_CONCAT(DISTINCT a, b ORDER BY d, c) +11,12,21 +CREATE TABLE t3 (a INT, b INT, c INT); +INSERT INTO t3 VALUES (1, 1, 1), (2, 1, 2), (3, 2, 1); +SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY b, c) FROM t3; +GROUP_CONCAT(DISTINCT a, b ORDER BY b, c) +11,21,32 +SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY c, b) FROM t3; +GROUP_CONCAT(DISTINCT a, b ORDER BY c, b) +11,32,21 +SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY a, b) FROM t1; +GROUP_CONCAT(DISTINCT a, b ORDER BY a, b) +11,22,23 +SELECT GROUP_CONCAT(DISTINCT b, a ORDER BY a, b) FROM t1; +GROUP_CONCAT(DISTINCT b, a ORDER BY a, b) +11,22,32 +SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY b, a) FROM t1; +GROUP_CONCAT(DISTINCT a, b ORDER BY b, a) +11,22,23 +SELECT GROUP_CONCAT(DISTINCT b, a ORDER BY a, b) FROM t1; +GROUP_CONCAT(DISTINCT b, a ORDER BY a, b) +11,22,32 +SELECT GROUP_CONCAT(DISTINCT a ORDER BY a, b) FROM t1; +GROUP_CONCAT(DISTINCT a ORDER BY a, b) +1,2 +SELECT GROUP_CONCAT(DISTINCT b ORDER BY b, a) FROM t1; +GROUP_CONCAT(DISTINCT b ORDER BY b, a) +1,2,3 +SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY a) FROM t1; +GROUP_CONCAT(DISTINCT a, b ORDER BY a) +11,23,22 +SELECT GROUP_CONCAT(DISTINCT b, a ORDER BY b) FROM t1; +GROUP_CONCAT(DISTINCT b, a ORDER BY b) +11,22,32 +DROP TABLE t1, t2, t3; End of 5.0 tests diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index abf717091af..4c1abb160c6 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1398,4 +1398,16 @@ SELECT COUNT(*), a FROM t1; COUNT(*) a 4 1 DROP TABLE t1; +set SQL_MODE=ONLY_FULL_GROUP_BY; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3),(4); +CREATE VIEW v1 AS SELECT a,(a + 1) AS y FROM t1; +EXPLAIN EXTENDED SELECT y FROM v1 GROUP BY v1.y; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using temporary; Using filesort +Warnings: +Note 1003 select (`test`.`t1`.`a` + 1) AS `y` from `test`.`t1` group by (`test`.`t1`.`a` + 1) +DROP VIEW v1; +DROP TABLE t1; +SET SQL_MODE=DEFAULT; End of 5.0 tests diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 5e3726a06d6..4dd8fb1531d 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1258,6 +1258,9 @@ DATE_ADD('20071108', INTERVAL 1 DAY) select DATE_ADD(20071108, INTERVAL 1 DAY); DATE_ADD(20071108, INTERVAL 1 DAY) 2007-11-09 +select LAST_DAY('2007-12-06 08:59:19.05') - INTERVAL 1 SECOND; +LAST_DAY('2007-12-06 08:59:19.05') - INTERVAL 1 SECOND +2007-12-30 23:59:59 End of 5.0 tests select date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND); date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND) diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index 1472fdfdd7a..268f290ddca 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -1478,3 +1478,39 @@ NULL 1 2 DROP TABLE t1; +CREATE TABLE t1 ( a INT, b INT ); +SELECT b c, (SELECT a FROM t1 WHERE b = c) +FROM t1; +c (SELECT a FROM t1 WHERE b = c) +SELECT b c, (SELECT a FROM t1 WHERE b = c) +FROM t1 +HAVING b = 10; +c (SELECT a FROM t1 WHERE b = c) +SELECT MAX(b) c, (SELECT a FROM t1 WHERE b = c) +FROM t1 +HAVING b = 10; +ERROR 42S22: Reference 'c' not supported (reference to group function) +SET @old_sql_mode = @@sql_mode; +SET @@sql_mode='ONLY_FULL_GROUP_BY'; +SELECT b c, (SELECT a FROM t1 WHERE b = c) +FROM t1; +c (SELECT a FROM t1 WHERE b = c) +SELECT b c, (SELECT a FROM t1 WHERE b = c) +FROM t1 +HAVING b = 10; +ERROR 42000: non-grouping field 'b' is used in HAVING clause +SELECT MAX(b) c, (SELECT a FROM t1 WHERE b = c) +FROM t1 +HAVING b = 10; +ERROR 42S22: Reference 'c' not supported (reference to group function) +INSERT INTO t1 VALUES (1, 1); +SELECT b c, (SELECT a FROM t1 WHERE b = c) +FROM t1; +c (SELECT a FROM t1 WHERE b = c) +1 1 +INSERT INTO t1 VALUES (2, 1); +SELECT b c, (SELECT a FROM t1 WHERE b = c) +FROM t1; +ERROR 21000: Subquery returns more than 1 row +DROP TABLE t1; +SET @@sql_mode = @old_sql_mode; diff --git a/mysql-test/r/have_local_infile.require b/mysql-test/r/have_local_infile.require new file mode 100644 index 00000000000..124540f7b77 --- /dev/null +++ b/mysql-test/r/have_local_infile.require @@ -0,0 +1,2 @@ +Variable_name Value +local_infile ON diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 87cf1acc10c..e9f00a667c0 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1349,7 +1349,7 @@ INSERT INTO t1 VALUES (191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2); EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL idx NULL NULL NULL 3 Using where; Using filesort +1 SIMPLE t1 ALL idx NULL NULL NULL 4 Using where; Using filesort SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; id type d 191 member 1 @@ -1609,4 +1609,29 @@ alter table t1 order by a; Warnings: Warning 1105 ORDER BY ignored as there is a user-defined clustered index in the table 't1' drop table t1; +CREATE TABLE t1 +(vid integer NOT NULL, +tid integer NOT NULL, +idx integer NOT NULL, +name varchar(128) NOT NULL, +type varchar(128) NULL, +PRIMARY KEY(idx, vid, tid), +UNIQUE(vid, tid, name) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES +(1,1,1,'pk',NULL),(2,1,1,'pk',NULL),(3,1,1,'pk',NULL),(4,1,1,'c1',NULL), +(5,1,1,'pk',NULL),(1,1,2,'c1',NULL),(2,1,2,'c1',NULL),(3,1,2,'c1',NULL), +(4,1,2,'c2',NULL),(5,1,2,'c1',NULL),(2,1,3,'c2',NULL),(3,1,3,'c2',NULL), +(4,1,3,'pk',NULL),(5,1,3,'c2',NULL), +(2,1,4,'c_extra',NULL),(3,1,4,'c_extra',NULL); +EXPLAIN SELECT * FROM t1 WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index vid PRIMARY 12 NULL 16 Using where +SELECT * FROM t1 WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; +vid tid idx name type +3 1 4 c_extra NULL +3 1 3 c2 NULL +3 1 2 c1 NULL +3 1 1 pk NULL +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 0bc01e95d2d..d96927deed5 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -627,7 +627,7 @@ a b 4 4 show master status /* there must be the UPDATE query event */; File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 268 +master-bin.000001 336 delete from t1; delete from t2; insert into t1 values (1,2),(3,4),(4,4); @@ -637,7 +637,7 @@ UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a; ERROR 23000: Duplicate entry '4' for key 'PRIMARY' show master status /* there must be the UPDATE query event */; File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 283 +master-bin.000001 351 drop table t1, t2; set @@session.binlog_format= @sav_binlog_format; drop table if exists t1, t2, t3; diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index e6485720c49..4ffcb7cdeeb 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -23,24 +23,33 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -drop table if exists t1,t2,t3,t4,t5,t03,t04/*!*/; +drop table if exists t1,t2,t3,t4,t5,t03,t04 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -create table t1 (word varchar(20))/*!*/; +create table t1 (word varchar(20)) +/*!*/; SET TIMESTAMP=1000000000/*!*/; -create table t2 (id int auto_increment not null primary key)/*!*/; +create table t2 (id int auto_increment not null primary key) +/*!*/; SET TIMESTAMP=1000000000/*!*/; -insert into t1 values ("abirvalg")/*!*/; +insert into t1 values ("abirvalg") +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1000000000/*!*/; -insert into t2 values ()/*!*/; +insert into t2 values () +/*!*/; SET TIMESTAMP=1000000000/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-1-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-2-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-3-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-4-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1 +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -56,7 +65,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values ("Alas")/*!*/; +insert into t1 values ("Alas") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -83,7 +93,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values ("Alas")/*!*/; +insert into t1 values ("Alas") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -100,24 +111,33 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -drop table if exists t1,t2,t3,t4,t5,t03,t04/*!*/; +drop table if exists t1,t2,t3,t4,t5,t03,t04 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -create table t1 (word varchar(20))/*!*/; +create table t1 (word varchar(20)) +/*!*/; SET TIMESTAMP=1000000000/*!*/; -create table t2 (id int auto_increment not null primary key)/*!*/; +create table t2 (id int auto_increment not null primary key) +/*!*/; SET TIMESTAMP=1000000000/*!*/; -insert into t1 values ("abirvalg")/*!*/; +insert into t1 values ("abirvalg") +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1000000000/*!*/; -insert into t2 values ()/*!*/; +insert into t2 values () +/*!*/; SET TIMESTAMP=1000000000/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-1-2' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-2-2' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-3-2' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-4-2' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1 +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -133,7 +153,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values ("Alas")/*!*/; +insert into t1 values ("Alas") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -160,7 +181,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values ("Alas")/*!*/; +insert into t1 values ("Alas") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -173,9 +195,11 @@ DELIMITER /*!*/; ROLLBACK/*!*/; use test/*!*/; SET TIMESTAMP=1108844556/*!*/; -BEGIN/*!*/; +BEGIN +/*!*/; SET TIMESTAMP=1108844555/*!*/; -insert t1 values (1)/*!*/; +insert t1 values (1) +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -185,9 +209,11 @@ ROLLBACK /* added by mysqlbinlog */; DELIMITER /*!*/; use test/*!*/; SET TIMESTAMP=1108844556/*!*/; -BEGIN/*!*/; +BEGIN +/*!*/; SET TIMESTAMP=1108844555/*!*/; -insert t1 values (1)/*!*/; +insert t1 values (1) +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -246,7 +272,8 @@ SET @@session.character_set_client=8,@@session.collation_connection=8,@@session. CREATE DEFINER=`root`@`localhost` procedure p1() begin select 1; -end/*!*/; +end +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -288,27 +315,36 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a varchar(64) character set utf8)/*!*/; +create table t1 (a varchar(64) character set utf8) +/*!*/; SET TIMESTAMP=1000000000/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-6-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1 +/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=7/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-7-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1 +/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=DEFAULT/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-8-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-9-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1 +/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=7/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-a-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-a-0' INTO table t1 +/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=DEFAULT/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-b-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-b-0' INTO table t1 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-c-0' INTO table t1 character set koi8r/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-c-0' INTO table t1 character set koi8r +/*!*/; SET TIMESTAMP=1000000000/*!*/; -drop table t1/*!*/; +drop table t1 +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -352,4 +388,29 @@ a b 1 root@localhost DROP DATABASE mysqltest1; DROP USER untrusted@localhost; +BUG#32580: mysqlbinlog cannot read binlog event with user variables +USE test; +SET BINLOG_FORMAT = STATEMENT; +FLUSH LOGS; +CREATE TABLE t1 (a_real FLOAT, an_int INT, a_decimal DECIMAL(5,2), a_string CHAR(32)); +SET @a_real = rand(20) * 1000; +SET @an_int = 1000; +SET @a_decimal = CAST(rand(19) * 999 AS DECIMAL(5,2)); +SET @a_string = 'Just a test'; +INSERT INTO t1 VALUES (@a_real, @an_int, @a_decimal, @a_string); +FLUSH LOGS; +SELECT * FROM t1; +a_real 158.883 +an_int 1000 +a_decimal 907.79 +a_string Just a test +DROP TABLE t1; +>> mysqlbinlog var/log/master-bin.000019 > var/tmp/bug32580.sql +>> mysql test < var/tmp/bug32580.sql +SELECT * FROM t1; +a_real 158.883 +an_int 1000 +a_decimal 907.79 +a_string Just a test +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/mysqlbinlog2.result b/mysql-test/r/mysqlbinlog2.result index 5347787d829..0c9ba34fc61 100644 --- a/mysql-test/r/mysqlbinlog2.result +++ b/mysql-test/r/mysqlbinlog2.result @@ -29,42 +29,48 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int auto_increment not null primary key, b char(3))/*!*/; +create table t1 (a int auto_increment not null primary key, b char(3)) +/*!*/; # at {pos} #{yymmdd} {HH:MM:SS} server id 1 end_log_pos {pos} Intvar SET INSERT_ID=1/*!*/; # at {pos} #{yymmdd} {HH:MM:SS} server id 1 end_log_pos {pos} Query thread_id={integer} exec_time={integer} error_code=0 SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; # at {pos} #{yymmdd} {HH:MM:SS} server id 1 end_log_pos {pos} Intvar SET INSERT_ID=2/*!*/; # at {pos} #{yymmdd} {HH:MM:SS} server id 1 end_log_pos {pos} Query thread_id={integer} exec_time={integer} error_code=0 SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; # at {pos} #{yymmdd} {HH:MM:SS} server id 1 end_log_pos {pos} Intvar SET INSERT_ID=3/*!*/; # at {pos} #{yymmdd} {HH:MM:SS} server id 1 end_log_pos {pos} Query thread_id={integer} exec_time={integer} error_code=0 SET TIMESTAMP=1579609944/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; # at {pos} #{yymmdd} {HH:MM:SS} server id 1 end_log_pos {pos} Intvar SET INSERT_ID=4/*!*/; # at {pos} #{yymmdd} {HH:MM:SS} server id 1 end_log_pos {pos} Query thread_id={integer} exec_time={integer} error_code=0 SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; # at {pos} #{yymmdd} {HH:MM:SS} server id 1 end_log_pos {pos} Intvar SET INSERT_ID=5/*!*/; # at {pos} #{yymmdd} {HH:MM:SS} server id 1 end_log_pos {pos} Query thread_id={integer} exec_time={integer} error_code=0 SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; # at {pos} #{yymmdd} {HH:MM:SS} server id 1 end_log_pos {pos} Rotate to master-bin.000002 pos: {pos} DELIMITER ; @@ -84,19 +90,24 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; SET INSERT_ID=3/*!*/; SET TIMESTAMP=1579609944/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -106,6 +117,7 @@ ROLLBACK /* added by mysqlbinlog */; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; +ROLLBACK/*!*/; SET INSERT_ID=4/*!*/; use test/*!*/; SET TIMESTAMP=1579609946/*!*/; @@ -113,10 +125,12 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -133,16 +147,20 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int auto_increment not null primary key, b char(3))/*!*/; +create table t1 (a int auto_increment not null primary key, b char(3)) +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; SET INSERT_ID=3/*!*/; SET TIMESTAMP=1579609944/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -152,6 +170,7 @@ ROLLBACK /* added by mysqlbinlog */; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; +ROLLBACK/*!*/; SET INSERT_ID=4/*!*/; use test/*!*/; SET TIMESTAMP=1579609946/*!*/; @@ -159,7 +178,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -177,13 +197,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -200,13 +223,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int auto_increment not null primary key, b char(3))/*!*/; +create table t1 (a int auto_increment not null primary key, b char(3)) +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -224,22 +250,28 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int auto_increment not null primary key, b char(3))/*!*/; +create table t1 (a int auto_increment not null primary key, b char(3)) +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; SET INSERT_ID=3/*!*/; SET TIMESTAMP=1579609944/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; DELIMITER /*!*/; SET INSERT_ID=6/*!*/; @@ -249,7 +281,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "f")/*!*/; +insert into t1 values(null, "f") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -267,19 +300,24 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; SET INSERT_ID=3/*!*/; SET TIMESTAMP=1579609944/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; DELIMITER /*!*/; SET INSERT_ID=6/*!*/; @@ -289,7 +327,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "f")/*!*/; +insert into t1 values(null, "f") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -299,6 +338,7 @@ ROLLBACK /* added by mysqlbinlog */; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; +ROLLBACK/*!*/; SET INSERT_ID=4/*!*/; use test/*!*/; SET TIMESTAMP=1579609946/*!*/; @@ -306,10 +346,12 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; DELIMITER /*!*/; SET INSERT_ID=6/*!*/; @@ -319,7 +361,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "f")/*!*/; +insert into t1 values(null, "f") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -336,22 +379,28 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int auto_increment not null primary key, b char(3))/*!*/; +create table t1 (a int auto_increment not null primary key, b char(3)) +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; SET INSERT_ID=3/*!*/; SET TIMESTAMP=1579609944/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; DELIMITER /*!*/; SET INSERT_ID=6/*!*/; @@ -372,13 +421,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; DELIMITER /*!*/; SET INSERT_ID=6/*!*/; @@ -388,7 +440,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "f")/*!*/; +insert into t1 values(null, "f") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -405,13 +458,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int auto_increment not null primary key, b char(3))/*!*/; +create table t1 (a int auto_increment not null primary key, b char(3)) +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -428,22 +484,28 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int auto_increment not null primary key, b char(3))/*!*/; +create table t1 (a int auto_increment not null primary key, b char(3)) +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; SET INSERT_ID=3/*!*/; SET TIMESTAMP=1579609944/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -461,19 +523,24 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; SET INSERT_ID=3/*!*/; SET TIMESTAMP=1579609944/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -490,10 +557,12 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -510,16 +579,20 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int auto_increment not null primary key, b char(3))/*!*/; +create table t1 (a int auto_increment not null primary key, b char(3)) +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; SET INSERT_ID=3/*!*/; SET TIMESTAMP=1579609944/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -536,7 +609,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -554,13 +628,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -577,13 +654,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int auto_increment not null primary key, b char(3))/*!*/; +create table t1 (a int auto_increment not null primary key, b char(3)) +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -600,22 +680,28 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int auto_increment not null primary key, b char(3))/*!*/; +create table t1 (a int auto_increment not null primary key, b char(3)) +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; SET INSERT_ID=3/*!*/; SET TIMESTAMP=1579609944/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; DELIMITER /*!*/; SET INSERT_ID=6/*!*/; @@ -625,7 +711,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "f")/*!*/; +insert into t1 values(null, "f") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -643,19 +730,24 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; SET INSERT_ID=3/*!*/; SET TIMESTAMP=1579609944/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; DELIMITER /*!*/; SET INSERT_ID=6/*!*/; @@ -665,7 +757,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "f")/*!*/; +insert into t1 values(null, "f") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -682,10 +775,12 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; DELIMITER /*!*/; SET INSERT_ID=6/*!*/; @@ -695,7 +790,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "f")/*!*/; +insert into t1 values(null, "f") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -712,22 +808,28 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int auto_increment not null primary key, b char(3))/*!*/; +create table t1 (a int auto_increment not null primary key, b char(3)) +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; SET INSERT_ID=3/*!*/; SET TIMESTAMP=1579609944/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; DELIMITER /*!*/; SET INSERT_ID=6/*!*/; @@ -748,13 +850,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; DELIMITER ; DELIMITER /*!*/; SET INSERT_ID=6/*!*/; @@ -764,7 +869,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t1 values(null, "f")/*!*/; +insert into t1 values(null, "f") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -781,13 +887,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int auto_increment not null primary key, b char(3))/*!*/; +create table t1 (a int auto_increment not null primary key, b char(3)) +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -804,25 +913,32 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int auto_increment not null primary key, b char(3))/*!*/; +create table t1 (a int auto_increment not null primary key, b char(3)) +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "a")/*!*/; +insert into t1 values(null, "a") +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1579609942/*!*/; -insert into t1 values(null, "b")/*!*/; +insert into t1 values(null, "b") +/*!*/; SET INSERT_ID=3/*!*/; SET TIMESTAMP=1579609944/*!*/; -insert into t1 values(null, "c")/*!*/; +insert into t1 values(null, "c") +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "d")/*!*/; +insert into t1 values(null, "d") +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1579609946/*!*/; -insert into t1 values(null, "e")/*!*/; +insert into t1 values(null, "e") +/*!*/; SET INSERT_ID=6/*!*/; SET TIMESTAMP=1579609943/*!*/; -insert into t1 values(null, "f")/*!*/; +insert into t1 values(null, "f") +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result index 345c9b07b98..5a2ebc37cc8 100644 --- a/mysql-test/r/null.result +++ b/mysql-test/r/null.result @@ -93,11 +93,9 @@ INSERT INTO t1 SET a = "", d= "2003-01-14 03:54:55"; Warnings: Warning 1265 Data truncated for column 'd' at row 1 UPDATE t1 SET d=1/NULL; -Warnings: -Warning 1265 Data truncated for column 'd' at row 1 +ERROR 23000: Column 'd' cannot be null UPDATE t1 SET d=NULL; -Warnings: -Warning 1048 Column 'd' cannot be null +ERROR 23000: Column 'd' cannot be null INSERT INTO t1 (a) values (null); ERROR 23000: Column 'a' cannot be null INSERT INTO t1 (a) values (1/null); @@ -132,7 +130,7 @@ Warning 1048 Column 'd' cannot be null Warning 1048 Column 'd' cannot be null select * from t1; a b c d - 0 0000-00-00 00:00:00 0 + 0 0000-00-00 00:00:00 2003 0 0000-00-00 00:00:00 0 0 0000-00-00 00:00:00 0 0 0000-00-00 00:00:00 0 diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result index ef53f227ec0..e10bcba36c2 100644 --- a/mysql-test/r/parser.result +++ b/mysql-test/r/parser.result @@ -527,3 +527,23 @@ SELECT * FROM t1 WHERE a = INTERVAL(3,2,1) + 1; a b 3 1998-01-01 00:00:00 DROP TABLE t1; +DROP TABLE IF EXISTS t1,t2,t3; +CREATE TABLE t1 (a1 INT, a2 INT, a3 INT, a4 DATETIME); +CREATE TABLE t2 LIKE t1; +CREATE TABLE t3 LIKE t1; +SELECT t1.* FROM t1 AS t0, { OJ t2 INNER JOIN t1 ON (t1.a1=t2.a1) } WHERE t0.a3=2; +a1 a2 a3 a4 +SELECT t1.*,t2.* FROM { OJ ((t1 INNER JOIN t2 ON (t1.a1=t2.a2)) LEFT OUTER JOIN t3 ON t3.a3=t2.a1)}; +a1 a2 a3 a4 a1 a2 a3 a4 +SELECT t1.*,t2.* FROM { OJ ((t1 LEFT OUTER JOIN t2 ON t1.a3=t2.a2) INNER JOIN t3 ON (t3.a1=t2.a2))}; +a1 a2 a3 a4 a1 a2 a3 a4 +SELECT t1.*,t2.* FROM { OJ (t1 LEFT OUTER JOIN t2 ON t1.a1=t2.a2) CROSS JOIN t3 ON (t3.a2=t2.a3)}; +a1 a2 a3 a4 a1 a2 a3 a4 +SELECT * FROM {oj t1 LEFT OUTER JOIN t2 ON t1.a1=t2.a3} WHERE t1.a2 > 10; +a1 a2 a3 a4 a1 a2 a3 a4 +SELECT {fn CONCAT(a1,a2)} FROM t1; +{fn CONCAT(a1,a2)} +UPDATE t3 SET a4={d '1789-07-14'} WHERE a1=0; +SELECT a1, a4 FROM t2 WHERE a4 LIKE {fn UCASE('1789-07-14')}; +a1 a4 +DROP TABLE t1, t2, t3; diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index 769c22a40d1..1a9bedf10da 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -1303,12 +1303,11 @@ a b set @arg00=NULL; set @arg01=2; execute stmt1 using @arg00, @arg01; -Warnings: -Warning 1048 Column 'a' cannot be null +ERROR 23000: Column 'a' cannot be null select a,b from t1 order by a; a b -0 two 1 one +2 two 3 three 4 four set @arg00=0; diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index 5d176f86192..9d075dd8e1f 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -1286,12 +1286,11 @@ a b set @arg00=NULL; set @arg01=2; execute stmt1 using @arg00, @arg01; -Warnings: -Warning 1048 Column 'a' cannot be null +ERROR 23000: Column 'a' cannot be null select a,b from t1 order by a; a b -0 two 1 one +2 two 3 three 4 four set @arg00=0; diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index 121e02fbe53..a1dce909760 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -1287,12 +1287,11 @@ a b set @arg00=NULL; set @arg01=2; execute stmt1 using @arg00, @arg01; -Warnings: -Warning 1048 Column 'a' cannot be null +ERROR 23000: Column 'a' cannot be null select a,b from t1 order by a; a b -0 two 1 one +2 two 3 three 4 four set @arg00=0; diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index c0182bdc81b..3b3a4dc13be 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -1329,12 +1329,11 @@ a b set @arg00=NULL; set @arg01=2; execute stmt1 using @arg00, @arg01; -Warnings: -Warning 1048 Column 'a' cannot be null +ERROR 23000: Column 'a' cannot be null select a,b from t1 order by a; a b -0 two 1 one +2 two 3 three 4 four set @arg00=0; @@ -4351,12 +4350,11 @@ a b set @arg00=NULL; set @arg01=2; execute stmt1 using @arg00, @arg01; -Warnings: -Warning 1048 Column 'a' cannot be null +ERROR 23000: Column 'a' cannot be null select a,b from t1 order by a; a b -0 two 1 one +2 two 3 three 4 four set @arg00=0; diff --git a/mysql-test/r/query_cache_debug.result b/mysql-test/r/query_cache_debug.result new file mode 100644 index 00000000000..f177bfac836 --- /dev/null +++ b/mysql-test/r/query_cache_debug.result @@ -0,0 +1,24 @@ +flush status; +set query_cache_type=DEMAND; +set global query_cache_size= 1024*1024*512; +drop table if exists t1; +create table t1 (a varchar(100)); +insert into t1 values ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +Activate debug hook and attempt to retrieve the statement from the cache. +set session debug='+d,wait_in_query_cache_insert'; +select SQL_CACHE * from t1;; +On a second connection; clear the query cache. +show status like 'Qcache_queries_in_cache'; +Variable_name Value +Qcache_queries_in_cache 1 +set global query_cache_size= 0; +Signal the debug hook to release the lock. +select id from information_schema.processlist where state='wait_in_query_cache_insert' into @thread_id; +kill query @thread_id; +Show query cache status. +show status like 'Qcache_queries_in_cache'; +Variable_name Value +Qcache_queries_in_cache 0 +set global query_cache_size= 0; +use test; +drop table t1; diff --git a/mysql-test/r/skip_grants.result b/mysql-test/r/skip_grants.result index bf0f16a174f..b523f2edc9f 100644 --- a/mysql-test/r/skip_grants.result +++ b/mysql-test/r/skip_grants.result @@ -72,10 +72,6 @@ count(*) select count(*) from information_schema.USER_PRIVILEGES; count(*) 0 -CREATE FUNCTION a RETURNS STRING SONAME ''; -ERROR HY000: Can't initialize function 'a'; UDFs are unavailable with the --skip-grant-tables option -DROP FUNCTION a; -ERROR 42000: FUNCTION test.a does not exist End of 5.0 tests # # Bug#29817 Queries with UDF fail with non-descriptive error diff --git a/mysql-test/r/sp-code.result b/mysql-test/r/sp-code.result index 018173e723d..ca5c5b42102 100644 --- a/mysql-test/r/sp-code.result +++ b/mysql-test/r/sp-code.result @@ -733,6 +733,115 @@ optimizer: keep hreturn drop table t1; drop procedure proc_26977_broken; drop procedure proc_26977_works; +drop procedure if exists proc_33618_h; +drop procedure if exists proc_33618_c; +create procedure proc_33618_h(num int) +begin +declare count1 int default '0'; +declare vb varchar(30); +declare last_row int; +while(num>=1) do +set num=num-1; +begin +declare cur1 cursor for select `a` from t_33618; +declare continue handler for not found set last_row = 1; +set last_row:=0; +open cur1; +rep1: +repeat +begin +declare exit handler for 1062 begin end; +fetch cur1 into vb; +if (last_row = 1) then +## should generate a hpop instruction here +leave rep1; +end if; +end; +until last_row=1 +end repeat; +close cur1; +end; +end while; +end// +create procedure proc_33618_c(num int) +begin +declare count1 int default '0'; +declare vb varchar(30); +declare last_row int; +while(num>=1) do +set num=num-1; +begin +declare cur1 cursor for select `a` from t_33618; +declare continue handler for not found set last_row = 1; +set last_row:=0; +open cur1; +rep1: +repeat +begin +declare cur2 cursor for select `b` from t_33618; +fetch cur1 into vb; +if (last_row = 1) then +## should generate a cpop instruction here +leave rep1; +end if; +end; +until last_row=1 +end repeat; +close cur1; +end; +end while; +end// +show procedure code proc_33618_h; +Pos Instruction +0 set count1@1 _latin1'0' +1 set vb@2 NULL +2 set last_row@3 NULL +3 jump_if_not 24(24) (num@0 >= 1) +4 set num@0 (num@0 - 1) +5 cpush cur1@0 +6 hpush_jump 9 4 CONTINUE +7 set last_row@3 1 +8 hreturn 4 +9 set last_row@3 0 +10 copen cur1@0 +11 hpush_jump 13 4 EXIT +12 hreturn 0 17 +13 cfetch cur1@0 vb@2 +14 jump_if_not 17(17) (last_row@3 = 1) +15 hpop 1 +16 jump 19 +17 hpop 1 +18 jump_if_not 11(19) (last_row@3 = 1) +19 cclose cur1@0 +20 hpop 1 +21 cpop 1 +22 jump 3 +show procedure code proc_33618_c; +Pos Instruction +0 set count1@1 _latin1'0' +1 set vb@2 NULL +2 set last_row@3 NULL +3 jump_if_not 23(23) (num@0 >= 1) +4 set num@0 (num@0 - 1) +5 cpush cur1@0 +6 hpush_jump 9 4 CONTINUE +7 set last_row@3 1 +8 hreturn 4 +9 set last_row@3 0 +10 copen cur1@0 +11 cpush cur2@1 +12 cfetch cur1@0 vb@2 +13 jump_if_not 16(16) (last_row@3 = 1) +14 cpop 1 +15 jump 18 +16 cpop 1 +17 jump_if_not 11(18) (last_row@3 = 1) +18 cclose cur1@0 +19 hpop 1 +20 cpop 1 +21 jump 3 +drop procedure proc_33618_h; +drop procedure proc_33618_c; End of 5.0 tests. CREATE PROCEDURE p1() BEGIN diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index b81f8ea64c9..c33c378340e 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1579,3 +1579,51 @@ drop function f2; drop table t2; ERROR 42S02: Unknown table 't2' End of 5.1 tests +drop procedure if exists proc_33983_a; +drop procedure if exists proc_33983_b; +drop procedure if exists proc_33983_c; +drop procedure if exists proc_33983_d; +create procedure proc_33983_a() +begin +label1: +begin +label2: +begin +select 1; +end label1; +end; +end| +ERROR 42000: End-label label1 without match +create procedure proc_33983_b() +begin +label1: +repeat +label2: +repeat +select 1; +until FALSE end repeat label1; +until FALSE end repeat; +end| +ERROR 42000: End-label label1 without match +create procedure proc_33983_c() +begin +label1: +while TRUE do +label2: +while TRUE do +select 1; +end while label1; +end while; +end| +ERROR 42000: End-label label1 without match +create procedure proc_33983_d() +begin +label1: +loop +label2: +loop +select 1; +end loop label1; +end loop; +end| +ERROR 42000: End-label label1 without match diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 68aa278585f..50ece83b258 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6812,7 +6812,59 @@ DROP PROCEDURE db28318_b.t2; DROP DATABASE db28318_a; DROP DATABASE db28318_b; use test; -End of 5.0 tests +DROP TABLE IF EXISTS t1; +DROP PROCEDURE IF EXISTS bug29770; +CREATE TABLE t1(a int); +CREATE PROCEDURE bug29770() +BEGIN +DECLARE CONTINUE HANDLER FOR SQLSTATE '42S22' SET @state:= 'run'; +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @exception:= 'run'; +SELECT x FROM t1; +END| +CALL bug29770(); +SELECT @state, @exception; +@state @exception +run NULL +DROP TABLE t1; +DROP PROCEDURE bug29770; +use test; +drop table if exists t_33618; +drop procedure if exists proc_33618; +create table t_33618 (`a` int, unique(`a`), `b` varchar(30)) engine=myisam; +insert into t_33618 (`a`,`b`) values (1,'1'),(2,'2'); +create procedure proc_33618(num int) +begin +declare count1 int default '0'; +declare vb varchar(30); +declare last_row int; +while(num>=1) do +set num=num-1; +begin +declare cur1 cursor for select `a` from t_33618; +declare continue handler for not found set last_row = 1; +set last_row:=0; +open cur1; +rep1: +repeat +begin +declare exit handler for 1062 begin end; +fetch cur1 into vb; +if (last_row = 1) then +leave rep1; +end if; +end; +until last_row=1 +end repeat; +close cur1; +end; +end while; +end// +call proc_33618(20); +drop table t_33618; +drop procedure proc_33618; +# ------------------------------------------------------------------ +# -- End of 5.0 tests +# ------------------------------------------------------------------ # # Bug#20550. @@ -6911,4 +6963,6 @@ END latin1 latin1_swedish_ci latin1_swedish_ci DROP FUNCTION f1; -End of 5.1 tests +# ------------------------------------------------------------------ +# -- End of 5.1 tests +# ------------------------------------------------------------------ diff --git a/mysql-test/r/sp_trans_log.result b/mysql-test/r/sp_trans_log.result index a835b06858b..7a6173b89e2 100644 --- a/mysql-test/r/sp_trans_log.result +++ b/mysql-test/r/sp_trans_log.result @@ -16,6 +16,7 @@ insert into t2 values (bug23333(),1)| ERROR 23000: Duplicate entry '1' for key 'PRIMARY' show binlog events from 106 /* with fixes for #23333 will show there is the query */| Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query 1 # # master-bin.000001 # Table_map 1 # # master-bin.000001 # Table_map 1 # # master-bin.000001 # Write_rows 1 # # diff --git a/mysql-test/r/strict_autoinc_4bdb.result b/mysql-test/r/strict_autoinc_4bdb.result deleted file mode 100644 index 2e8980e435b..00000000000 --- a/mysql-test/r/strict_autoinc_4bdb.result +++ /dev/null @@ -1,28 +0,0 @@ -drop table if exists t1; -set @org_mode=@@sql_mode; -create table t1 -( -`a` tinyint(4) NOT NULL auto_increment, -primary key (`a`) -) engine = 'BDB' ; -set @@sql_mode='strict_all_tables'; -insert into t1 values(1000); -ERROR 22003: Out of range value for column 'a' at row 1 -select count(*) from t1; -count(*) -0 -set auto_increment_increment=1000; -set auto_increment_offset=700; -insert into t1 values(null); -ERROR 22003: Out of range value for column 'a' at row 1 -select count(*) from t1; -count(*) -0 -set @@sql_mode=@org_mode; -insert into t1 values(null); -Warnings: -Warning 1264 Out of range value for column 'a' at row 1 -select * from t1; -a -127 -drop table t1; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 209f67e5386..4c7c79dd1c1 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4282,6 +4282,63 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION (SELECT 1 FROM t2 WHERE t1.a = t2.a))' at line 2 DROP TABLE t1,t2; +create table t1(f11 int, f12 int); +create table t2(f21 int unsigned not null, f22 int, f23 varchar(10)); +insert into t1 values(1,1),(2,2), (3, 3); +set session sort_buffer_size= 33*1024; +select count(*) from t1 where f12 = +(select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1); +count(*) +3 +drop table t1,t2; +CREATE TABLE t4 ( +f7 varchar(32) collate utf8_bin NOT NULL default '', +f10 varchar(32) collate utf8_bin default NULL, +PRIMARY KEY (f7) +); +INSERT INTO t4 VALUES(1,1), (2,null); +CREATE TABLE t2 ( +f4 varchar(32) collate utf8_bin NOT NULL default '', +f2 varchar(50) collate utf8_bin default NULL, +f3 varchar(10) collate utf8_bin default NULL, +PRIMARY KEY (f4), +UNIQUE KEY uk1 (f2) +); +INSERT INTO t2 VALUES(1,1,null), (2,2,null); +CREATE TABLE t1 ( +f8 varchar(32) collate utf8_bin NOT NULL default '', +f1 varchar(10) collate utf8_bin default NULL, +f9 varchar(32) collate utf8_bin default NULL, +PRIMARY KEY (f8) +); +INSERT INTO t1 VALUES (1,'P',1), (2,'P',1), (3,'R',2); +CREATE TABLE t3 ( +f6 varchar(32) collate utf8_bin NOT NULL default '', +f5 varchar(50) collate utf8_bin default NULL, +PRIMARY KEY (f6) +); +INSERT INTO t3 VALUES (1,null), (2,null); +SELECT +IF(t1.f1 = 'R', a1.f2, t2.f2) AS a4, +IF(t1.f1 = 'R', a1.f3, t2.f3) AS f3, +SUM( +IF( +(SELECT VPC.f2 +FROM t2 VPC, t4 a2, t2 a3 +WHERE +VPC.f4 = a2.f10 AND a3.f2 = a4 +LIMIT 1) IS NULL, +0, +t3.f5 +) +) AS a6 +FROM +t2, t3, t1 JOIN t2 a1 ON t1.f9 = a1.f4 +GROUP BY a4; +a4 f3 a6 +1 NULL NULL +2 NULL NULL +DROP TABLE t1, t2, t3, t4; End of 5.0 tests. CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (2,22),(1,11),(2,22); diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index 5921991bf50..7cb71831bce 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -260,6 +260,11 @@ INSERT INTO t1 VALUES ('1000-00-00'); ERROR 22007: Incorrect date value: '1000-00-00' for column 'a' at row 1 SET SQL_MODE=DEFAULT; DROP TABLE t1,t2; +CREATE TABLE t1 SELECT curdate() AS f1; +SELECT hour(f1), minute(f1), second(f1) FROM t1; +hour(f1) minute(f1) second(f1) +0 0 0 +DROP TABLE t1; End of 5.0 tests create table t1 (a date, primary key (a))engine=memory; insert into t1 values ('0000-01-01'), ('0000-00-01'), ('0001-01-01'); diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index e37a398d22e..3e5f6a9b504 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -786,10 +786,6 @@ from (select 1 as s,'t' as t union select null, null ) as sub1; select group_concat(t) from t1 group by week(date)/10; group_concat(t) t -Warnings: -Warning 1292 Incorrect datetime value: '0000-00-00' -Warning 1292 Incorrect datetime value: '0000-00-00' -Warning 1292 Incorrect datetime value: '0000-00-00' drop table t1; CREATE TABLE t1 ( qty decimal(16,6) default NULL, @@ -798,7 +794,7 @@ dps tinyint(3) unsigned default NULL INSERT INTO t1 VALUES (1.1325,3); SELECT ROUND(qty,3), dps, ROUND(qty,dps) FROM t1; ROUND(qty,3) dps ROUND(qty,dps) -1.133 3 1.133 +1.133 3 1.133000 DROP TABLE t1; SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS '%'; % @@ -889,4 +885,65 @@ c 1000 1234567890 DROP TABLE t1, t2, t3, t4; +CREATE TABLE t1( a DECIMAL(4, 3), b INT ); +INSERT INTO t1 VALUES ( 1, 5 ), ( 2, 4 ), ( 3, 3 ), ( 4, 2 ), ( 5, 1 ); +SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c; +a b c +1.000 5 1.000 +2.000 4 2.000 +3.000 3 3.000 +4.000 2 4.000 +5.000 1 5.000 +SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c DESC; +a b c +5.000 1 5.000 +4.000 2 4.000 +3.000 3 3.000 +2.000 4 2.000 +1.000 5 1.000 +CREATE TABLE t2 ( a INT, b INT, c DECIMAL(5, 4) ); +INSERT INTO t2 VALUES ( 0, 1, 1.2345 ), ( 1, 2, 1.2345 ), +( 3, 3, 1.2345 ), ( 2, 4, 1.2345 ); +SELECT a, b, MAX(ROUND(c, a)) +FROM t2 +GROUP BY a, b +ORDER BY b; +a b MAX(ROUND(c, a)) +0 1 1.0000 +1 2 1.2000 +3 3 1.2350 +2 4 1.2300 +SELECT a, b, ROUND(c, a) +FROM t2; +a b ROUND(c, a) +0 1 1.0000 +1 2 1.2000 +3 3 1.2350 +2 4 1.2300 +CREATE TABLE t3( a INT, b DECIMAL(6, 3) ); +INSERT INTO t3 VALUES( 0, 1.5 ); +SELECT ROUND( b, a ) FROM t3; +ROUND( b, a ) +2.000 +CREATE TABLE t4( a INT, b DECIMAL( 12, 0) ); +INSERT INTO t4 VALUES( -9, 1.5e9 ); +SELECT ROUND( b, a ) FROM t4; +ROUND( b, a ) +2000000000 +CREATE TABLE t5( a INT, b DECIMAL( 13, 12 ) ); +INSERT INTO t5 VALUES( 0, 1.5 ); +INSERT INTO t5 VALUES( 9, 1.5e-9 ); +SELECT ROUND( b, a ) FROM t5; +ROUND( b, a ) +2.000000000000 +0.000000002000 +CREATE TABLE t6( a INT ); +INSERT INTO t6 VALUES( 6 / 8 ); +SELECT * FROM t6; +a +1 +SELECT ROUND(20061108085411.000002); +ROUND(20061108085411.000002) +20061108085411 +DROP TABLE t1, t2, t3, t4, t5, t6; End of 5.0 tests diff --git a/mysql-test/r/udf_skip_grants.result b/mysql-test/r/udf_skip_grants.result new file mode 100644 index 00000000000..8d7081ebf6f --- /dev/null +++ b/mysql-test/r/udf_skip_grants.result @@ -0,0 +1,5 @@ +CREATE FUNCTION a RETURNS STRING SONAME ''; +ERROR HY000: Can't initialize function 'a'; UDFs are unavailable with the --skip-grant-tables option +DROP FUNCTION a; +ERROR 42000: FUNCTION test.a does not exist +End of 5.0 tests diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 6fc630ec33c..295451867c8 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1445,4 +1445,79 @@ select @var; 1 (select 2) union (select 1 into @var); ERROR 42000: Result consisted of more than one row +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (10), (20); +CREATE TABLE t2 (b int); +INSERT INTO t2 VALUES (10), (50), (50); +SELECT a,1 FROM t1 +UNION +SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP +ORDER BY a; +a 1 +NULL 3 +10 1 +20 1 +50 2 +SELECT a,1 FROM t1 +UNION +SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP +ORDER BY a DESC; +a 1 +50 2 +20 1 +10 1 +NULL 3 +SELECT a,1 FROM t1 +UNION +SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP +ORDER BY a ASC LIMIT 3; +a 1 +NULL 3 +10 1 +20 1 +SELECT a,1 FROM t1 +UNION ALL +SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP +ORDER BY a DESC; +a 1 +50 2 +20 1 +10 1 +10 1 +NULL 3 +SELECT a,1 FROM t1 +UNION +(SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP ORDER BY a); +ERROR HY000: Incorrect usage of CUBE/ROLLUP and ORDER BY +SELECT a,1 FROM t1 +UNION ALL +SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP ORDER BY a +UNION +SELECT 1,1; +ERROR HY000: Incorrect usage of UNION and ORDER BY +DROP TABLE t1,t2; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1), (2), (3); +CREATE TABLE t2 SELECT * FROM (SELECT NULL) a UNION SELECT a FROM t1; +DESC t2; +Field Type Null Key Default Extra +NULL int(11) YES NULL +CREATE TABLE t3 SELECT a FROM t1 UNION SELECT * FROM (SELECT NULL) a; +DESC t3; +Field Type Null Key Default Extra +a int(11) YES NULL +CREATE TABLE t4 SELECT NULL; +DESC t4; +Field Type Null Key Default Extra +NULL binary(0) YES NULL +CREATE TABLE t5 SELECT NULL UNION SELECT NULL; +DESC t5; +Field Type Null Key Default Extra +NULL binary(0) YES NULL +CREATE TABLE t6 +SELECT * FROM (SELECT * FROM (SELECT NULL)a) b UNION SELECT a FROM t1; +DESC t6; +Field Type Null Key Default Extra +NULL int(11) YES NULL +DROP TABLE t1, t2, t3, t4, t5, t6; End of 5.0 tests diff --git a/mysql-test/r/user_var-binlog.result b/mysql-test/r/user_var-binlog.result index b76b399c9e2..44fcfc0c478 100644 --- a/mysql-test/r/user_var-binlog.result +++ b/mysql-test/r/user_var-binlog.result @@ -25,11 +25,13 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -INSERT INTO t1 VALUES(@`a b`)/*!*/; +INSERT INTO t1 VALUES(@`a b`) +/*!*/; SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`/*!*/; SET @`var2`:=_binary 0x61 COLLATE `binary`/*!*/; SET TIMESTAMP=10000/*!*/; -insert into t1 values (@var1),(@var2)/*!*/; +insert into t1 values (@var1),(@var2) +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 2971af7347d..09b997797b4 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3597,6 +3597,22 @@ DROP VIEW v1; DROP VIEW v2; DROP VIEW v3; DROP TABLE t1; +# +# Bug#29477: Not all fields of the target table were checked to have +# a default value when inserting into a view. +# +create table t1(f1 int, f2 int not null); +create view v1 as select f1 from t1; +insert into v1 values(1); +Warnings: +Warning 1423 Field of view 'test.v1' underlying table doesn't have a default value +set @old_mode=@@sql_mode; +set @@sql_mode=traditional; +insert into v1 values(1); +ERROR HY000: Field of view 'test.v1' underlying table doesn't have a default value +set @@sql_mode=@old_mode; +drop view v1; +drop table t1; End of 5.0 tests. DROP DATABASE IF EXISTS `d-1`; CREATE DATABASE `d-1`; diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index 2929328a9b1..249cd583345 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -98,8 +98,7 @@ Warning 1265 Data truncated for column 'c' at row 1 Warning 1265 Data truncated for column 'c' at row 2 alter table t1 add d char(2); update t1 set a=NULL where a=10; -Warnings: -Warning 1048 Column 'a' cannot be null +ERROR 23000: Column 'a' cannot be null update t1 set c='mysql ab' where c='test'; Warnings: Warning 1265 Data truncated for column 'c' at row 4 diff --git a/mysql-test/std_data/bug30435_10k_items.txt b/mysql-test/std_data/bug30435_10k_items.txt new file mode 100644 index 00000000000..9812045fd89 --- /dev/null +++ b/mysql-test/std_data/bug30435_10k_items.txt @@ -0,0 +1,10000 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741 +742 +743 +744 +745 +746 +747 +748 +749 +750 +751 +752 +753 +754 +755 +756 +757 +758 +759 +760 +761 +762 +763 +764 +765 +766 +767 +768 +769 +770 +771 +772 +773 +774 +775 +776 +777 +778 +779 +780 +781 +782 +783 +784 +785 +786 +787 +788 +789 +790 +791 +792 +793 +794 +795 +796 +797 +798 +799 +800 +801 +802 +803 +804 +805 +806 +807 +808 +809 +810 +811 +812 +813 +814 +815 +816 +817 +818 +819 +820 +821 +822 +823 +824 +825 +826 +827 +828 +829 +830 +831 +832 +833 +834 +835 +836 +837 +838 +839 +840 +841 +842 +843 +844 +845 +846 +847 +848 +849 +850 +851 +852 +853 +854 +855 +856 +857 +858 +859 +860 +861 +862 +863 +864 +865 +866 +867 +868 +869 +870 +871 +872 +873 +874 +875 +876 +877 +878 +879 +880 +881 +882 +883 +884 +885 +886 +887 +888 +889 +890 +891 +892 +893 +894 +895 +896 +897 +898 +899 +900 +901 +902 +903 +904 +905 +906 +907 +908 +909 +910 +911 +912 +913 +914 +915 +916 +917 +918 +919 +920 +921 +922 +923 +924 +925 +926 +927 +928 +929 +930 +931 +932 +933 +934 +935 +936 +937 +938 +939 +940 +941 +942 +943 +944 +945 +946 +947 +948 +949 +950 +951 +952 +953 +954 +955 +956 +957 +958 +959 +960 +961 +962 +963 +964 +965 +966 +967 +968 +969 +970 +971 +972 +973 +974 +975 +976 +977 +978 +979 +980 +981 +982 +983 +984 +985 +986 +987 +988 +989 +990 +991 +992 +993 +994 +995 +996 +997 +998 +999 +1000 +1001 +1002 +1003 +1004 +1005 +1006 +1007 +1008 +1009 +1010 +1011 +1012 +1013 +1014 +1015 +1016 +1017 +1018 +1019 +1020 +1021 +1022 +1023 +1024 +1025 +1026 +1027 +1028 +1029 +1030 +1031 +1032 +1033 +1034 +1035 +1036 +1037 +1038 +1039 +1040 +1041 +1042 +1043 +1044 +1045 +1046 +1047 +1048 +1049 +1050 +1051 +1052 +1053 +1054 +1055 +1056 +1057 +1058 +1059 +1060 +1061 +1062 +1063 +1064 +1065 +1066 +1067 +1068 +1069 +1070 +1071 +1072 +1073 +1074 +1075 +1076 +1077 +1078 +1079 +1080 +1081 +1082 +1083 +1084 +1085 +1086 +1087 +1088 +1089 +1090 +1091 +1092 +1093 +1094 +1095 +1096 +1097 +1098 +1099 +1100 +1101 +1102 +1103 +1104 +1105 +1106 +1107 +1108 +1109 +1110 +1111 +1112 +1113 +1114 +1115 +1116 +1117 +1118 +1119 +1120 +1121 +1122 +1123 +1124 +1125 +1126 +1127 +1128 +1129 +1130 +1131 +1132 +1133 +1134 +1135 +1136 +1137 +1138 +1139 +1140 +1141 +1142 +1143 +1144 +1145 +1146 +1147 +1148 +1149 +1150 +1151 +1152 +1153 +1154 +1155 +1156 +1157 +1158 +1159 +1160 +1161 +1162 +1163 +1164 +1165 +1166 +1167 +1168 +1169 +1170 +1171 +1172 +1173 +1174 +1175 +1176 +1177 +1178 +1179 +1180 +1181 +1182 +1183 +1184 +1185 +1186 +1187 +1188 +1189 +1190 +1191 +1192 +1193 +1194 +1195 +1196 +1197 +1198 +1199 +1200 +1201 +1202 +1203 +1204 +1205 +1206 +1207 +1208 +1209 +1210 +1211 +1212 +1213 +1214 +1215 +1216 +1217 +1218 +1219 +1220 +1221 +1222 +1223 +1224 +1225 +1226 +1227 +1228 +1229 +1230 +1231 +1232 +1233 +1234 +1235 +1236 +1237 +1238 +1239 +1240 +1241 +1242 +1243 +1244 +1245 +1246 +1247 +1248 +1249 +1250 +1251 +1252 +1253 +1254 +1255 +1256 +1257 +1258 +1259 +1260 +1261 +1262 +1263 +1264 +1265 +1266 +1267 +1268 +1269 +1270 +1271 +1272 +1273 +1274 +1275 +1276 +1277 +1278 +1279 +1280 +1281 +1282 +1283 +1284 +1285 +1286 +1287 +1288 +1289 +1290 +1291 +1292 +1293 +1294 +1295 +1296 +1297 +1298 +1299 +1300 +1301 +1302 +1303 +1304 +1305 +1306 +1307 +1308 +1309 +1310 +1311 +1312 +1313 +1314 +1315 +1316 +1317 +1318 +1319 +1320 +1321 +1322 +1323 +1324 +1325 +1326 +1327 +1328 +1329 +1330 +1331 +1332 +1333 +1334 +1335 +1336 +1337 +1338 +1339 +1340 +1341 +1342 +1343 +1344 +1345 +1346 +1347 +1348 +1349 +1350 +1351 +1352 +1353 +1354 +1355 +1356 +1357 +1358 +1359 +1360 +1361 +1362 +1363 +1364 +1365 +1366 +1367 +1368 +1369 +1370 +1371 +1372 +1373 +1374 +1375 +1376 +1377 +1378 +1379 +1380 +1381 +1382 +1383 +1384 +1385 +1386 +1387 +1388 +1389 +1390 +1391 +1392 +1393 +1394 +1395 +1396 +1397 +1398 +1399 +1400 +1401 +1402 +1403 +1404 +1405 +1406 +1407 +1408 +1409 +1410 +1411 +1412 +1413 +1414 +1415 +1416 +1417 +1418 +1419 +1420 +1421 +1422 +1423 +1424 +1425 +1426 +1427 +1428 +1429 +1430 +1431 +1432 +1433 +1434 +1435 +1436 +1437 +1438 +1439 +1440 +1441 +1442 +1443 +1444 +1445 +1446 +1447 +1448 +1449 +1450 +1451 +1452 +1453 +1454 +1455 +1456 +1457 +1458 +1459 +1460 +1461 +1462 +1463 +1464 +1465 +1466 +1467 +1468 +1469 +1470 +1471 +1472 +1473 +1474 +1475 +1476 +1477 +1478 +1479 +1480 +1481 +1482 +1483 +1484 +1485 +1486 +1487 +1488 +1489 +1490 +1491 +1492 +1493 +1494 +1495 +1496 +1497 +1498 +1499 +1500 +1501 +1502 +1503 +1504 +1505 +1506 +1507 +1508 +1509 +1510 +1511 +1512 +1513 +1514 +1515 +1516 +1517 +1518 +1519 +1520 +1521 +1522 +1523 +1524 +1525 +1526 +1527 +1528 +1529 +1530 +1531 +1532 +1533 +1534 +1535 +1536 +1537 +1538 +1539 +1540 +1541 +1542 +1543 +1544 +1545 +1546 +1547 +1548 +1549 +1550 +1551 +1552 +1553 +1554 +1555 +1556 +1557 +1558 +1559 +1560 +1561 +1562 +1563 +1564 +1565 +1566 +1567 +1568 +1569 +1570 +1571 +1572 +1573 +1574 +1575 +1576 +1577 +1578 +1579 +1580 +1581 +1582 +1583 +1584 +1585 +1586 +1587 +1588 +1589 +1590 +1591 +1592 +1593 +1594 +1595 +1596 +1597 +1598 +1599 +1600 +1601 +1602 +1603 +1604 +1605 +1606 +1607 +1608 +1609 +1610 +1611 +1612 +1613 +1614 +1615 +1616 +1617 +1618 +1619 +1620 +1621 +1622 +1623 +1624 +1625 +1626 +1627 +1628 +1629 +1630 +1631 +1632 +1633 +1634 +1635 +1636 +1637 +1638 +1639 +1640 +1641 +1642 +1643 +1644 +1645 +1646 +1647 +1648 +1649 +1650 +1651 +1652 +1653 +1654 +1655 +1656 +1657 +1658 +1659 +1660 +1661 +1662 +1663 +1664 +1665 +1666 +1667 +1668 +1669 +1670 +1671 +1672 +1673 +1674 +1675 +1676 +1677 +1678 +1679 +1680 +1681 +1682 +1683 +1684 +1685 +1686 +1687 +1688 +1689 +1690 +1691 +1692 +1693 +1694 +1695 +1696 +1697 +1698 +1699 +1700 +1701 +1702 +1703 +1704 +1705 +1706 +1707 +1708 +1709 +1710 +1711 +1712 +1713 +1714 +1715 +1716 +1717 +1718 +1719 +1720 +1721 +1722 +1723 +1724 +1725 +1726 +1727 +1728 +1729 +1730 +1731 +1732 +1733 +1734 +1735 +1736 +1737 +1738 +1739 +1740 +1741 +1742 +1743 +1744 +1745 +1746 +1747 +1748 +1749 +1750 +1751 +1752 +1753 +1754 +1755 +1756 +1757 +1758 +1759 +1760 +1761 +1762 +1763 +1764 +1765 +1766 +1767 +1768 +1769 +1770 +1771 +1772 +1773 +1774 +1775 +1776 +1777 +1778 +1779 +1780 +1781 +1782 +1783 +1784 +1785 +1786 +1787 +1788 +1789 +1790 +1791 +1792 +1793 +1794 +1795 +1796 +1797 +1798 +1799 +1800 +1801 +1802 +1803 +1804 +1805 +1806 +1807 +1808 +1809 +1810 +1811 +1812 +1813 +1814 +1815 +1816 +1817 +1818 +1819 +1820 +1821 +1822 +1823 +1824 +1825 +1826 +1827 +1828 +1829 +1830 +1831 +1832 +1833 +1834 +1835 +1836 +1837 +1838 +1839 +1840 +1841 +1842 +1843 +1844 +1845 +1846 +1847 +1848 +1849 +1850 +1851 +1852 +1853 +1854 +1855 +1856 +1857 +1858 +1859 +1860 +1861 +1862 +1863 +1864 +1865 +1866 +1867 +1868 +1869 +1870 +1871 +1872 +1873 +1874 +1875 +1876 +1877 +1878 +1879 +1880 +1881 +1882 +1883 +1884 +1885 +1886 +1887 +1888 +1889 +1890 +1891 +1892 +1893 +1894 +1895 +1896 +1897 +1898 +1899 +1900 +1901 +1902 +1903 +1904 +1905 +1906 +1907 +1908 +1909 +1910 +1911 +1912 +1913 +1914 +1915 +1916 +1917 +1918 +1919 +1920 +1921 +1922 +1923 +1924 +1925 +1926 +1927 +1928 +1929 +1930 +1931 +1932 +1933 +1934 +1935 +1936 +1937 +1938 +1939 +1940 +1941 +1942 +1943 +1944 +1945 +1946 +1947 +1948 +1949 +1950 +1951 +1952 +1953 +1954 +1955 +1956 +1957 +1958 +1959 +1960 +1961 +1962 +1963 +1964 +1965 +1966 +1967 +1968 +1969 +1970 +1971 +1972 +1973 +1974 +1975 +1976 +1977 +1978 +1979 +1980 +1981 +1982 +1983 +1984 +1985 +1986 +1987 +1988 +1989 +1990 +1991 +1992 +1993 +1994 +1995 +1996 +1997 +1998 +1999 +2000 +2001 +2002 +2003 +2004 +2005 +2006 +2007 +2008 +2009 +2010 +2011 +2012 +2013 +2014 +2015 +2016 +2017 +2018 +2019 +2020 +2021 +2022 +2023 +2024 +2025 +2026 +2027 +2028 +2029 +2030 +2031 +2032 +2033 +2034 +2035 +2036 +2037 +2038 +2039 +2040 +2041 +2042 +2043 +2044 +2045 +2046 +2047 +2048 +2049 +2050 +2051 +2052 +2053 +2054 +2055 +2056 +2057 +2058 +2059 +2060 +2061 +2062 +2063 +2064 +2065 +2066 +2067 +2068 +2069 +2070 +2071 +2072 +2073 +2074 +2075 +2076 +2077 +2078 +2079 +2080 +2081 +2082 +2083 +2084 +2085 +2086 +2087 +2088 +2089 +2090 +2091 +2092 +2093 +2094 +2095 +2096 +2097 +2098 +2099 +2100 +2101 +2102 +2103 +2104 +2105 +2106 +2107 +2108 +2109 +2110 +2111 +2112 +2113 +2114 +2115 +2116 +2117 +2118 +2119 +2120 +2121 +2122 +2123 +2124 +2125 +2126 +2127 +2128 +2129 +2130 +2131 +2132 +2133 +2134 +2135 +2136 +2137 +2138 +2139 +2140 +2141 +2142 +2143 +2144 +2145 +2146 +2147 +2148 +2149 +2150 +2151 +2152 +2153 +2154 +2155 +2156 +2157 +2158 +2159 +2160 +2161 +2162 +2163 +2164 +2165 +2166 +2167 +2168 +2169 +2170 +2171 +2172 +2173 +2174 +2175 +2176 +2177 +2178 +2179 +2180 +2181 +2182 +2183 +2184 +2185 +2186 +2187 +2188 +2189 +2190 +2191 +2192 +2193 +2194 +2195 +2196 +2197 +2198 +2199 +2200 +2201 +2202 +2203 +2204 +2205 +2206 +2207 +2208 +2209 +2210 +2211 +2212 +2213 +2214 +2215 +2216 +2217 +2218 +2219 +2220 +2221 +2222 +2223 +2224 +2225 +2226 +2227 +2228 +2229 +2230 +2231 +2232 +2233 +2234 +2235 +2236 +2237 +2238 +2239 +2240 +2241 +2242 +2243 +2244 +2245 +2246 +2247 +2248 +2249 +2250 +2251 +2252 +2253 +2254 +2255 +2256 +2257 +2258 +2259 +2260 +2261 +2262 +2263 +2264 +2265 +2266 +2267 +2268 +2269 +2270 +2271 +2272 +2273 +2274 +2275 +2276 +2277 +2278 +2279 +2280 +2281 +2282 +2283 +2284 +2285 +2286 +2287 +2288 +2289 +2290 +2291 +2292 +2293 +2294 +2295 +2296 +2297 +2298 +2299 +2300 +2301 +2302 +2303 +2304 +2305 +2306 +2307 +2308 +2309 +2310 +2311 +2312 +2313 +2314 +2315 +2316 +2317 +2318 +2319 +2320 +2321 +2322 +2323 +2324 +2325 +2326 +2327 +2328 +2329 +2330 +2331 +2332 +2333 +2334 +2335 +2336 +2337 +2338 +2339 +2340 +2341 +2342 +2343 +2344 +2345 +2346 +2347 +2348 +2349 +2350 +2351 +2352 +2353 +2354 +2355 +2356 +2357 +2358 +2359 +2360 +2361 +2362 +2363 +2364 +2365 +2366 +2367 +2368 +2369 +2370 +2371 +2372 +2373 +2374 +2375 +2376 +2377 +2378 +2379 +2380 +2381 +2382 +2383 +2384 +2385 +2386 +2387 +2388 +2389 +2390 +2391 +2392 +2393 +2394 +2395 +2396 +2397 +2398 +2399 +2400 +2401 +2402 +2403 +2404 +2405 +2406 +2407 +2408 +2409 +2410 +2411 +2412 +2413 +2414 +2415 +2416 +2417 +2418 +2419 +2420 +2421 +2422 +2423 +2424 +2425 +2426 +2427 +2428 +2429 +2430 +2431 +2432 +2433 +2434 +2435 +2436 +2437 +2438 +2439 +2440 +2441 +2442 +2443 +2444 +2445 +2446 +2447 +2448 +2449 +2450 +2451 +2452 +2453 +2454 +2455 +2456 +2457 +2458 +2459 +2460 +2461 +2462 +2463 +2464 +2465 +2466 +2467 +2468 +2469 +2470 +2471 +2472 +2473 +2474 +2475 +2476 +2477 +2478 +2479 +2480 +2481 +2482 +2483 +2484 +2485 +2486 +2487 +2488 +2489 +2490 +2491 +2492 +2493 +2494 +2495 +2496 +2497 +2498 +2499 +2500 +2501 +2502 +2503 +2504 +2505 +2506 +2507 +2508 +2509 +2510 +2511 +2512 +2513 +2514 +2515 +2516 +2517 +2518 +2519 +2520 +2521 +2522 +2523 +2524 +2525 +2526 +2527 +2528 +2529 +2530 +2531 +2532 +2533 +2534 +2535 +2536 +2537 +2538 +2539 +2540 +2541 +2542 +2543 +2544 +2545 +2546 +2547 +2548 +2549 +2550 +2551 +2552 +2553 +2554 +2555 +2556 +2557 +2558 +2559 +2560 +2561 +2562 +2563 +2564 +2565 +2566 +2567 +2568 +2569 +2570 +2571 +2572 +2573 +2574 +2575 +2576 +2577 +2578 +2579 +2580 +2581 +2582 +2583 +2584 +2585 +2586 +2587 +2588 +2589 +2590 +2591 +2592 +2593 +2594 +2595 +2596 +2597 +2598 +2599 +2600 +2601 +2602 +2603 +2604 +2605 +2606 +2607 +2608 +2609 +2610 +2611 +2612 +2613 +2614 +2615 +2616 +2617 +2618 +2619 +2620 +2621 +2622 +2623 +2624 +2625 +2626 +2627 +2628 +2629 +2630 +2631 +2632 +2633 +2634 +2635 +2636 +2637 +2638 +2639 +2640 +2641 +2642 +2643 +2644 +2645 +2646 +2647 +2648 +2649 +2650 +2651 +2652 +2653 +2654 +2655 +2656 +2657 +2658 +2659 +2660 +2661 +2662 +2663 +2664 +2665 +2666 +2667 +2668 +2669 +2670 +2671 +2672 +2673 +2674 +2675 +2676 +2677 +2678 +2679 +2680 +2681 +2682 +2683 +2684 +2685 +2686 +2687 +2688 +2689 +2690 +2691 +2692 +2693 +2694 +2695 +2696 +2697 +2698 +2699 +2700 +2701 +2702 +2703 +2704 +2705 +2706 +2707 +2708 +2709 +2710 +2711 +2712 +2713 +2714 +2715 +2716 +2717 +2718 +2719 +2720 +2721 +2722 +2723 +2724 +2725 +2726 +2727 +2728 +2729 +2730 +2731 +2732 +2733 +2734 +2735 +2736 +2737 +2738 +2739 +2740 +2741 +2742 +2743 +2744 +2745 +2746 +2747 +2748 +2749 +2750 +2751 +2752 +2753 +2754 +2755 +2756 +2757 +2758 +2759 +2760 +2761 +2762 +2763 +2764 +2765 +2766 +2767 +2768 +2769 +2770 +2771 +2772 +2773 +2774 +2775 +2776 +2777 +2778 +2779 +2780 +2781 +2782 +2783 +2784 +2785 +2786 +2787 +2788 +2789 +2790 +2791 +2792 +2793 +2794 +2795 +2796 +2797 +2798 +2799 +2800 +2801 +2802 +2803 +2804 +2805 +2806 +2807 +2808 +2809 +2810 +2811 +2812 +2813 +2814 +2815 +2816 +2817 +2818 +2819 +2820 +2821 +2822 +2823 +2824 +2825 +2826 +2827 +2828 +2829 +2830 +2831 +2832 +2833 +2834 +2835 +2836 +2837 +2838 +2839 +2840 +2841 +2842 +2843 +2844 +2845 +2846 +2847 +2848 +2849 +2850 +2851 +2852 +2853 +2854 +2855 +2856 +2857 +2858 +2859 +2860 +2861 +2862 +2863 +2864 +2865 +2866 +2867 +2868 +2869 +2870 +2871 +2872 +2873 +2874 +2875 +2876 +2877 +2878 +2879 +2880 +2881 +2882 +2883 +2884 +2885 +2886 +2887 +2888 +2889 +2890 +2891 +2892 +2893 +2894 +2895 +2896 +2897 +2898 +2899 +2900 +2901 +2902 +2903 +2904 +2905 +2906 +2907 +2908 +2909 +2910 +2911 +2912 +2913 +2914 +2915 +2916 +2917 +2918 +2919 +2920 +2921 +2922 +2923 +2924 +2925 +2926 +2927 +2928 +2929 +2930 +2931 +2932 +2933 +2934 +2935 +2936 +2937 +2938 +2939 +2940 +2941 +2942 +2943 +2944 +2945 +2946 +2947 +2948 +2949 +2950 +2951 +2952 +2953 +2954 +2955 +2956 +2957 +2958 +2959 +2960 +2961 +2962 +2963 +2964 +2965 +2966 +2967 +2968 +2969 +2970 +2971 +2972 +2973 +2974 +2975 +2976 +2977 +2978 +2979 +2980 +2981 +2982 +2983 +2984 +2985 +2986 +2987 +2988 +2989 +2990 +2991 +2992 +2993 +2994 +2995 +2996 +2997 +2998 +2999 +3000 +3001 +3002 +3003 +3004 +3005 +3006 +3007 +3008 +3009 +3010 +3011 +3012 +3013 +3014 +3015 +3016 +3017 +3018 +3019 +3020 +3021 +3022 +3023 +3024 +3025 +3026 +3027 +3028 +3029 +3030 +3031 +3032 +3033 +3034 +3035 +3036 +3037 +3038 +3039 +3040 +3041 +3042 +3043 +3044 +3045 +3046 +3047 +3048 +3049 +3050 +3051 +3052 +3053 +3054 +3055 +3056 +3057 +3058 +3059 +3060 +3061 +3062 +3063 +3064 +3065 +3066 +3067 +3068 +3069 +3070 +3071 +3072 +3073 +3074 +3075 +3076 +3077 +3078 +3079 +3080 +3081 +3082 +3083 +3084 +3085 +3086 +3087 +3088 +3089 +3090 +3091 +3092 +3093 +3094 +3095 +3096 +3097 +3098 +3099 +3100 +3101 +3102 +3103 +3104 +3105 +3106 +3107 +3108 +3109 +3110 +3111 +3112 +3113 +3114 +3115 +3116 +3117 +3118 +3119 +3120 +3121 +3122 +3123 +3124 +3125 +3126 +3127 +3128 +3129 +3130 +3131 +3132 +3133 +3134 +3135 +3136 +3137 +3138 +3139 +3140 +3141 +3142 +3143 +3144 +3145 +3146 +3147 +3148 +3149 +3150 +3151 +3152 +3153 +3154 +3155 +3156 +3157 +3158 +3159 +3160 +3161 +3162 +3163 +3164 +3165 +3166 +3167 +3168 +3169 +3170 +3171 +3172 +3173 +3174 +3175 +3176 +3177 +3178 +3179 +3180 +3181 +3182 +3183 +3184 +3185 +3186 +3187 +3188 +3189 +3190 +3191 +3192 +3193 +3194 +3195 +3196 +3197 +3198 +3199 +3200 +3201 +3202 +3203 +3204 +3205 +3206 +3207 +3208 +3209 +3210 +3211 +3212 +3213 +3214 +3215 +3216 +3217 +3218 +3219 +3220 +3221 +3222 +3223 +3224 +3225 +3226 +3227 +3228 +3229 +3230 +3231 +3232 +3233 +3234 +3235 +3236 +3237 +3238 +3239 +3240 +3241 +3242 +3243 +3244 +3245 +3246 +3247 +3248 +3249 +3250 +3251 +3252 +3253 +3254 +3255 +3256 +3257 +3258 +3259 +3260 +3261 +3262 +3263 +3264 +3265 +3266 +3267 +3268 +3269 +3270 +3271 +3272 +3273 +3274 +3275 +3276 +3277 +3278 +3279 +3280 +3281 +3282 +3283 +3284 +3285 +3286 +3287 +3288 +3289 +3290 +3291 +3292 +3293 +3294 +3295 +3296 +3297 +3298 +3299 +3300 +3301 +3302 +3303 +3304 +3305 +3306 +3307 +3308 +3309 +3310 +3311 +3312 +3313 +3314 +3315 +3316 +3317 +3318 +3319 +3320 +3321 +3322 +3323 +3324 +3325 +3326 +3327 +3328 +3329 +3330 +3331 +3332 +3333 +3334 +3335 +3336 +3337 +3338 +3339 +3340 +3341 +3342 +3343 +3344 +3345 +3346 +3347 +3348 +3349 +3350 +3351 +3352 +3353 +3354 +3355 +3356 +3357 +3358 +3359 +3360 +3361 +3362 +3363 +3364 +3365 +3366 +3367 +3368 +3369 +3370 +3371 +3372 +3373 +3374 +3375 +3376 +3377 +3378 +3379 +3380 +3381 +3382 +3383 +3384 +3385 +3386 +3387 +3388 +3389 +3390 +3391 +3392 +3393 +3394 +3395 +3396 +3397 +3398 +3399 +3400 +3401 +3402 +3403 +3404 +3405 +3406 +3407 +3408 +3409 +3410 +3411 +3412 +3413 +3414 +3415 +3416 +3417 +3418 +3419 +3420 +3421 +3422 +3423 +3424 +3425 +3426 +3427 +3428 +3429 +3430 +3431 +3432 +3433 +3434 +3435 +3436 +3437 +3438 +3439 +3440 +3441 +3442 +3443 +3444 +3445 +3446 +3447 +3448 +3449 +3450 +3451 +3452 +3453 +3454 +3455 +3456 +3457 +3458 +3459 +3460 +3461 +3462 +3463 +3464 +3465 +3466 +3467 +3468 +3469 +3470 +3471 +3472 +3473 +3474 +3475 +3476 +3477 +3478 +3479 +3480 +3481 +3482 +3483 +3484 +3485 +3486 +3487 +3488 +3489 +3490 +3491 +3492 +3493 +3494 +3495 +3496 +3497 +3498 +3499 +3500 +3501 +3502 +3503 +3504 +3505 +3506 +3507 +3508 +3509 +3510 +3511 +3512 +3513 +3514 +3515 +3516 +3517 +3518 +3519 +3520 +3521 +3522 +3523 +3524 +3525 +3526 +3527 +3528 +3529 +3530 +3531 +3532 +3533 +3534 +3535 +3536 +3537 +3538 +3539 +3540 +3541 +3542 +3543 +3544 +3545 +3546 +3547 +3548 +3549 +3550 +3551 +3552 +3553 +3554 +3555 +3556 +3557 +3558 +3559 +3560 +3561 +3562 +3563 +3564 +3565 +3566 +3567 +3568 +3569 +3570 +3571 +3572 +3573 +3574 +3575 +3576 +3577 +3578 +3579 +3580 +3581 +3582 +3583 +3584 +3585 +3586 +3587 +3588 +3589 +3590 +3591 +3592 +3593 +3594 +3595 +3596 +3597 +3598 +3599 +3600 +3601 +3602 +3603 +3604 +3605 +3606 +3607 +3608 +3609 +3610 +3611 +3612 +3613 +3614 +3615 +3616 +3617 +3618 +3619 +3620 +3621 +3622 +3623 +3624 +3625 +3626 +3627 +3628 +3629 +3630 +3631 +3632 +3633 +3634 +3635 +3636 +3637 +3638 +3639 +3640 +3641 +3642 +3643 +3644 +3645 +3646 +3647 +3648 +3649 +3650 +3651 +3652 +3653 +3654 +3655 +3656 +3657 +3658 +3659 +3660 +3661 +3662 +3663 +3664 +3665 +3666 +3667 +3668 +3669 +3670 +3671 +3672 +3673 +3674 +3675 +3676 +3677 +3678 +3679 +3680 +3681 +3682 +3683 +3684 +3685 +3686 +3687 +3688 +3689 +3690 +3691 +3692 +3693 +3694 +3695 +3696 +3697 +3698 +3699 +3700 +3701 +3702 +3703 +3704 +3705 +3706 +3707 +3708 +3709 +3710 +3711 +3712 +3713 +3714 +3715 +3716 +3717 +3718 +3719 +3720 +3721 +3722 +3723 +3724 +3725 +3726 +3727 +3728 +3729 +3730 +3731 +3732 +3733 +3734 +3735 +3736 +3737 +3738 +3739 +3740 +3741 +3742 +3743 +3744 +3745 +3746 +3747 +3748 +3749 +3750 +3751 +3752 +3753 +3754 +3755 +3756 +3757 +3758 +3759 +3760 +3761 +3762 +3763 +3764 +3765 +3766 +3767 +3768 +3769 +3770 +3771 +3772 +3773 +3774 +3775 +3776 +3777 +3778 +3779 +3780 +3781 +3782 +3783 +3784 +3785 +3786 +3787 +3788 +3789 +3790 +3791 +3792 +3793 +3794 +3795 +3796 +3797 +3798 +3799 +3800 +3801 +3802 +3803 +3804 +3805 +3806 +3807 +3808 +3809 +3810 +3811 +3812 +3813 +3814 +3815 +3816 +3817 +3818 +3819 +3820 +3821 +3822 +3823 +3824 +3825 +3826 +3827 +3828 +3829 +3830 +3831 +3832 +3833 +3834 +3835 +3836 +3837 +3838 +3839 +3840 +3841 +3842 +3843 +3844 +3845 +3846 +3847 +3848 +3849 +3850 +3851 +3852 +3853 +3854 +3855 +3856 +3857 +3858 +3859 +3860 +3861 +3862 +3863 +3864 +3865 +3866 +3867 +3868 +3869 +3870 +3871 +3872 +3873 +3874 +3875 +3876 +3877 +3878 +3879 +3880 +3881 +3882 +3883 +3884 +3885 +3886 +3887 +3888 +3889 +3890 +3891 +3892 +3893 +3894 +3895 +3896 +3897 +3898 +3899 +3900 +3901 +3902 +3903 +3904 +3905 +3906 +3907 +3908 +3909 +3910 +3911 +3912 +3913 +3914 +3915 +3916 +3917 +3918 +3919 +3920 +3921 +3922 +3923 +3924 +3925 +3926 +3927 +3928 +3929 +3930 +3931 +3932 +3933 +3934 +3935 +3936 +3937 +3938 +3939 +3940 +3941 +3942 +3943 +3944 +3945 +3946 +3947 +3948 +3949 +3950 +3951 +3952 +3953 +3954 +3955 +3956 +3957 +3958 +3959 +3960 +3961 +3962 +3963 +3964 +3965 +3966 +3967 +3968 +3969 +3970 +3971 +3972 +3973 +3974 +3975 +3976 +3977 +3978 +3979 +3980 +3981 +3982 +3983 +3984 +3985 +3986 +3987 +3988 +3989 +3990 +3991 +3992 +3993 +3994 +3995 +3996 +3997 +3998 +3999 +4000 +4001 +4002 +4003 +4004 +4005 +4006 +4007 +4008 +4009 +4010 +4011 +4012 +4013 +4014 +4015 +4016 +4017 +4018 +4019 +4020 +4021 +4022 +4023 +4024 +4025 +4026 +4027 +4028 +4029 +4030 +4031 +4032 +4033 +4034 +4035 +4036 +4037 +4038 +4039 +4040 +4041 +4042 +4043 +4044 +4045 +4046 +4047 +4048 +4049 +4050 +4051 +4052 +4053 +4054 +4055 +4056 +4057 +4058 +4059 +4060 +4061 +4062 +4063 +4064 +4065 +4066 +4067 +4068 +4069 +4070 +4071 +4072 +4073 +4074 +4075 +4076 +4077 +4078 +4079 +4080 +4081 +4082 +4083 +4084 +4085 +4086 +4087 +4088 +4089 +4090 +4091 +4092 +4093 +4094 +4095 +4096 +4097 +4098 +4099 +4100 +4101 +4102 +4103 +4104 +4105 +4106 +4107 +4108 +4109 +4110 +4111 +4112 +4113 +4114 +4115 +4116 +4117 +4118 +4119 +4120 +4121 +4122 +4123 +4124 +4125 +4126 +4127 +4128 +4129 +4130 +4131 +4132 +4133 +4134 +4135 +4136 +4137 +4138 +4139 +4140 +4141 +4142 +4143 +4144 +4145 +4146 +4147 +4148 +4149 +4150 +4151 +4152 +4153 +4154 +4155 +4156 +4157 +4158 +4159 +4160 +4161 +4162 +4163 +4164 +4165 +4166 +4167 +4168 +4169 +4170 +4171 +4172 +4173 +4174 +4175 +4176 +4177 +4178 +4179 +4180 +4181 +4182 +4183 +4184 +4185 +4186 +4187 +4188 +4189 +4190 +4191 +4192 +4193 +4194 +4195 +4196 +4197 +4198 +4199 +4200 +4201 +4202 +4203 +4204 +4205 +4206 +4207 +4208 +4209 +4210 +4211 +4212 +4213 +4214 +4215 +4216 +4217 +4218 +4219 +4220 +4221 +4222 +4223 +4224 +4225 +4226 +4227 +4228 +4229 +4230 +4231 +4232 +4233 +4234 +4235 +4236 +4237 +4238 +4239 +4240 +4241 +4242 +4243 +4244 +4245 +4246 +4247 +4248 +4249 +4250 +4251 +4252 +4253 +4254 +4255 +4256 +4257 +4258 +4259 +4260 +4261 +4262 +4263 +4264 +4265 +4266 +4267 +4268 +4269 +4270 +4271 +4272 +4273 +4274 +4275 +4276 +4277 +4278 +4279 +4280 +4281 +4282 +4283 +4284 +4285 +4286 +4287 +4288 +4289 +4290 +4291 +4292 +4293 +4294 +4295 +4296 +4297 +4298 +4299 +4300 +4301 +4302 +4303 +4304 +4305 +4306 +4307 +4308 +4309 +4310 +4311 +4312 +4313 +4314 +4315 +4316 +4317 +4318 +4319 +4320 +4321 +4322 +4323 +4324 +4325 +4326 +4327 +4328 +4329 +4330 +4331 +4332 +4333 +4334 +4335 +4336 +4337 +4338 +4339 +4340 +4341 +4342 +4343 +4344 +4345 +4346 +4347 +4348 +4349 +4350 +4351 +4352 +4353 +4354 +4355 +4356 +4357 +4358 +4359 +4360 +4361 +4362 +4363 +4364 +4365 +4366 +4367 +4368 +4369 +4370 +4371 +4372 +4373 +4374 +4375 +4376 +4377 +4378 +4379 +4380 +4381 +4382 +4383 +4384 +4385 +4386 +4387 +4388 +4389 +4390 +4391 +4392 +4393 +4394 +4395 +4396 +4397 +4398 +4399 +4400 +4401 +4402 +4403 +4404 +4405 +4406 +4407 +4408 +4409 +4410 +4411 +4412 +4413 +4414 +4415 +4416 +4417 +4418 +4419 +4420 +4421 +4422 +4423 +4424 +4425 +4426 +4427 +4428 +4429 +4430 +4431 +4432 +4433 +4434 +4435 +4436 +4437 +4438 +4439 +4440 +4441 +4442 +4443 +4444 +4445 +4446 +4447 +4448 +4449 +4450 +4451 +4452 +4453 +4454 +4455 +4456 +4457 +4458 +4459 +4460 +4461 +4462 +4463 +4464 +4465 +4466 +4467 +4468 +4469 +4470 +4471 +4472 +4473 +4474 +4475 +4476 +4477 +4478 +4479 +4480 +4481 +4482 +4483 +4484 +4485 +4486 +4487 +4488 +4489 +4490 +4491 +4492 +4493 +4494 +4495 +4496 +4497 +4498 +4499 +4500 +4501 +4502 +4503 +4504 +4505 +4506 +4507 +4508 +4509 +4510 +4511 +4512 +4513 +4514 +4515 +4516 +4517 +4518 +4519 +4520 +4521 +4522 +4523 +4524 +4525 +4526 +4527 +4528 +4529 +4530 +4531 +4532 +4533 +4534 +4535 +4536 +4537 +4538 +4539 +4540 +4541 +4542 +4543 +4544 +4545 +4546 +4547 +4548 +4549 +4550 +4551 +4552 +4553 +4554 +4555 +4556 +4557 +4558 +4559 +4560 +4561 +4562 +4563 +4564 +4565 +4566 +4567 +4568 +4569 +4570 +4571 +4572 +4573 +4574 +4575 +4576 +4577 +4578 +4579 +4580 +4581 +4582 +4583 +4584 +4585 +4586 +4587 +4588 +4589 +4590 +4591 +4592 +4593 +4594 +4595 +4596 +4597 +4598 +4599 +4600 +4601 +4602 +4603 +4604 +4605 +4606 +4607 +4608 +4609 +4610 +4611 +4612 +4613 +4614 +4615 +4616 +4617 +4618 +4619 +4620 +4621 +4622 +4623 +4624 +4625 +4626 +4627 +4628 +4629 +4630 +4631 +4632 +4633 +4634 +4635 +4636 +4637 +4638 +4639 +4640 +4641 +4642 +4643 +4644 +4645 +4646 +4647 +4648 +4649 +4650 +4651 +4652 +4653 +4654 +4655 +4656 +4657 +4658 +4659 +4660 +4661 +4662 +4663 +4664 +4665 +4666 +4667 +4668 +4669 +4670 +4671 +4672 +4673 +4674 +4675 +4676 +4677 +4678 +4679 +4680 +4681 +4682 +4683 +4684 +4685 +4686 +4687 +4688 +4689 +4690 +4691 +4692 +4693 +4694 +4695 +4696 +4697 +4698 +4699 +4700 +4701 +4702 +4703 +4704 +4705 +4706 +4707 +4708 +4709 +4710 +4711 +4712 +4713 +4714 +4715 +4716 +4717 +4718 +4719 +4720 +4721 +4722 +4723 +4724 +4725 +4726 +4727 +4728 +4729 +4730 +4731 +4732 +4733 +4734 +4735 +4736 +4737 +4738 +4739 +4740 +4741 +4742 +4743 +4744 +4745 +4746 +4747 +4748 +4749 +4750 +4751 +4752 +4753 +4754 +4755 +4756 +4757 +4758 +4759 +4760 +4761 +4762 +4763 +4764 +4765 +4766 +4767 +4768 +4769 +4770 +4771 +4772 +4773 +4774 +4775 +4776 +4777 +4778 +4779 +4780 +4781 +4782 +4783 +4784 +4785 +4786 +4787 +4788 +4789 +4790 +4791 +4792 +4793 +4794 +4795 +4796 +4797 +4798 +4799 +4800 +4801 +4802 +4803 +4804 +4805 +4806 +4807 +4808 +4809 +4810 +4811 +4812 +4813 +4814 +4815 +4816 +4817 +4818 +4819 +4820 +4821 +4822 +4823 +4824 +4825 +4826 +4827 +4828 +4829 +4830 +4831 +4832 +4833 +4834 +4835 +4836 +4837 +4838 +4839 +4840 +4841 +4842 +4843 +4844 +4845 +4846 +4847 +4848 +4849 +4850 +4851 +4852 +4853 +4854 +4855 +4856 +4857 +4858 +4859 +4860 +4861 +4862 +4863 +4864 +4865 +4866 +4867 +4868 +4869 +4870 +4871 +4872 +4873 +4874 +4875 +4876 +4877 +4878 +4879 +4880 +4881 +4882 +4883 +4884 +4885 +4886 +4887 +4888 +4889 +4890 +4891 +4892 +4893 +4894 +4895 +4896 +4897 +4898 +4899 +4900 +4901 +4902 +4903 +4904 +4905 +4906 +4907 +4908 +4909 +4910 +4911 +4912 +4913 +4914 +4915 +4916 +4917 +4918 +4919 +4920 +4921 +4922 +4923 +4924 +4925 +4926 +4927 +4928 +4929 +4930 +4931 +4932 +4933 +4934 +4935 +4936 +4937 +4938 +4939 +4940 +4941 +4942 +4943 +4944 +4945 +4946 +4947 +4948 +4949 +4950 +4951 +4952 +4953 +4954 +4955 +4956 +4957 +4958 +4959 +4960 +4961 +4962 +4963 +4964 +4965 +4966 +4967 +4968 +4969 +4970 +4971 +4972 +4973 +4974 +4975 +4976 +4977 +4978 +4979 +4980 +4981 +4982 +4983 +4984 +4985 +4986 +4987 +4988 +4989 +4990 +4991 +4992 +4993 +4994 +4995 +4996 +4997 +4998 +4999 +5000 +5001 +5002 +5003 +5004 +5005 +5006 +5007 +5008 +5009 +5010 +5011 +5012 +5013 +5014 +5015 +5016 +5017 +5018 +5019 +5020 +5021 +5022 +5023 +5024 +5025 +5026 +5027 +5028 +5029 +5030 +5031 +5032 +5033 +5034 +5035 +5036 +5037 +5038 +5039 +5040 +5041 +5042 +5043 +5044 +5045 +5046 +5047 +5048 +5049 +5050 +5051 +5052 +5053 +5054 +5055 +5056 +5057 +5058 +5059 +5060 +5061 +5062 +5063 +5064 +5065 +5066 +5067 +5068 +5069 +5070 +5071 +5072 +5073 +5074 +5075 +5076 +5077 +5078 +5079 +5080 +5081 +5082 +5083 +5084 +5085 +5086 +5087 +5088 +5089 +5090 +5091 +5092 +5093 +5094 +5095 +5096 +5097 +5098 +5099 +5100 +5101 +5102 +5103 +5104 +5105 +5106 +5107 +5108 +5109 +5110 +5111 +5112 +5113 +5114 +5115 +5116 +5117 +5118 +5119 +5120 +5121 +5122 +5123 +5124 +5125 +5126 +5127 +5128 +5129 +5130 +5131 +5132 +5133 +5134 +5135 +5136 +5137 +5138 +5139 +5140 +5141 +5142 +5143 +5144 +5145 +5146 +5147 +5148 +5149 +5150 +5151 +5152 +5153 +5154 +5155 +5156 +5157 +5158 +5159 +5160 +5161 +5162 +5163 +5164 +5165 +5166 +5167 +5168 +5169 +5170 +5171 +5172 +5173 +5174 +5175 +5176 +5177 +5178 +5179 +5180 +5181 +5182 +5183 +5184 +5185 +5186 +5187 +5188 +5189 +5190 +5191 +5192 +5193 +5194 +5195 +5196 +5197 +5198 +5199 +5200 +5201 +5202 +5203 +5204 +5205 +5206 +5207 +5208 +5209 +5210 +5211 +5212 +5213 +5214 +5215 +5216 +5217 +5218 +5219 +5220 +5221 +5222 +5223 +5224 +5225 +5226 +5227 +5228 +5229 +5230 +5231 +5232 +5233 +5234 +5235 +5236 +5237 +5238 +5239 +5240 +5241 +5242 +5243 +5244 +5245 +5246 +5247 +5248 +5249 +5250 +5251 +5252 +5253 +5254 +5255 +5256 +5257 +5258 +5259 +5260 +5261 +5262 +5263 +5264 +5265 +5266 +5267 +5268 +5269 +5270 +5271 +5272 +5273 +5274 +5275 +5276 +5277 +5278 +5279 +5280 +5281 +5282 +5283 +5284 +5285 +5286 +5287 +5288 +5289 +5290 +5291 +5292 +5293 +5294 +5295 +5296 +5297 +5298 +5299 +5300 +5301 +5302 +5303 +5304 +5305 +5306 +5307 +5308 +5309 +5310 +5311 +5312 +5313 +5314 +5315 +5316 +5317 +5318 +5319 +5320 +5321 +5322 +5323 +5324 +5325 +5326 +5327 +5328 +5329 +5330 +5331 +5332 +5333 +5334 +5335 +5336 +5337 +5338 +5339 +5340 +5341 +5342 +5343 +5344 +5345 +5346 +5347 +5348 +5349 +5350 +5351 +5352 +5353 +5354 +5355 +5356 +5357 +5358 +5359 +5360 +5361 +5362 +5363 +5364 +5365 +5366 +5367 +5368 +5369 +5370 +5371 +5372 +5373 +5374 +5375 +5376 +5377 +5378 +5379 +5380 +5381 +5382 +5383 +5384 +5385 +5386 +5387 +5388 +5389 +5390 +5391 +5392 +5393 +5394 +5395 +5396 +5397 +5398 +5399 +5400 +5401 +5402 +5403 +5404 +5405 +5406 +5407 +5408 +5409 +5410 +5411 +5412 +5413 +5414 +5415 +5416 +5417 +5418 +5419 +5420 +5421 +5422 +5423 +5424 +5425 +5426 +5427 +5428 +5429 +5430 +5431 +5432 +5433 +5434 +5435 +5436 +5437 +5438 +5439 +5440 +5441 +5442 +5443 +5444 +5445 +5446 +5447 +5448 +5449 +5450 +5451 +5452 +5453 +5454 +5455 +5456 +5457 +5458 +5459 +5460 +5461 +5462 +5463 +5464 +5465 +5466 +5467 +5468 +5469 +5470 +5471 +5472 +5473 +5474 +5475 +5476 +5477 +5478 +5479 +5480 +5481 +5482 +5483 +5484 +5485 +5486 +5487 +5488 +5489 +5490 +5491 +5492 +5493 +5494 +5495 +5496 +5497 +5498 +5499 +5500 +5501 +5502 +5503 +5504 +5505 +5506 +5507 +5508 +5509 +5510 +5511 +5512 +5513 +5514 +5515 +5516 +5517 +5518 +5519 +5520 +5521 +5522 +5523 +5524 +5525 +5526 +5527 +5528 +5529 +5530 +5531 +5532 +5533 +5534 +5535 +5536 +5537 +5538 +5539 +5540 +5541 +5542 +5543 +5544 +5545 +5546 +5547 +5548 +5549 +5550 +5551 +5552 +5553 +5554 +5555 +5556 +5557 +5558 +5559 +5560 +5561 +5562 +5563 +5564 +5565 +5566 +5567 +5568 +5569 +5570 +5571 +5572 +5573 +5574 +5575 +5576 +5577 +5578 +5579 +5580 +5581 +5582 +5583 +5584 +5585 +5586 +5587 +5588 +5589 +5590 +5591 +5592 +5593 +5594 +5595 +5596 +5597 +5598 +5599 +5600 +5601 +5602 +5603 +5604 +5605 +5606 +5607 +5608 +5609 +5610 +5611 +5612 +5613 +5614 +5615 +5616 +5617 +5618 +5619 +5620 +5621 +5622 +5623 +5624 +5625 +5626 +5627 +5628 +5629 +5630 +5631 +5632 +5633 +5634 +5635 +5636 +5637 +5638 +5639 +5640 +5641 +5642 +5643 +5644 +5645 +5646 +5647 +5648 +5649 +5650 +5651 +5652 +5653 +5654 +5655 +5656 +5657 +5658 +5659 +5660 +5661 +5662 +5663 +5664 +5665 +5666 +5667 +5668 +5669 +5670 +5671 +5672 +5673 +5674 +5675 +5676 +5677 +5678 +5679 +5680 +5681 +5682 +5683 +5684 +5685 +5686 +5687 +5688 +5689 +5690 +5691 +5692 +5693 +5694 +5695 +5696 +5697 +5698 +5699 +5700 +5701 +5702 +5703 +5704 +5705 +5706 +5707 +5708 +5709 +5710 +5711 +5712 +5713 +5714 +5715 +5716 +5717 +5718 +5719 +5720 +5721 +5722 +5723 +5724 +5725 +5726 +5727 +5728 +5729 +5730 +5731 +5732 +5733 +5734 +5735 +5736 +5737 +5738 +5739 +5740 +5741 +5742 +5743 +5744 +5745 +5746 +5747 +5748 +5749 +5750 +5751 +5752 +5753 +5754 +5755 +5756 +5757 +5758 +5759 +5760 +5761 +5762 +5763 +5764 +5765 +5766 +5767 +5768 +5769 +5770 +5771 +5772 +5773 +5774 +5775 +5776 +5777 +5778 +5779 +5780 +5781 +5782 +5783 +5784 +5785 +5786 +5787 +5788 +5789 +5790 +5791 +5792 +5793 +5794 +5795 +5796 +5797 +5798 +5799 +5800 +5801 +5802 +5803 +5804 +5805 +5806 +5807 +5808 +5809 +5810 +5811 +5812 +5813 +5814 +5815 +5816 +5817 +5818 +5819 +5820 +5821 +5822 +5823 +5824 +5825 +5826 +5827 +5828 +5829 +5830 +5831 +5832 +5833 +5834 +5835 +5836 +5837 +5838 +5839 +5840 +5841 +5842 +5843 +5844 +5845 +5846 +5847 +5848 +5849 +5850 +5851 +5852 +5853 +5854 +5855 +5856 +5857 +5858 +5859 +5860 +5861 +5862 +5863 +5864 +5865 +5866 +5867 +5868 +5869 +5870 +5871 +5872 +5873 +5874 +5875 +5876 +5877 +5878 +5879 +5880 +5881 +5882 +5883 +5884 +5885 +5886 +5887 +5888 +5889 +5890 +5891 +5892 +5893 +5894 +5895 +5896 +5897 +5898 +5899 +5900 +5901 +5902 +5903 +5904 +5905 +5906 +5907 +5908 +5909 +5910 +5911 +5912 +5913 +5914 +5915 +5916 +5917 +5918 +5919 +5920 +5921 +5922 +5923 +5924 +5925 +5926 +5927 +5928 +5929 +5930 +5931 +5932 +5933 +5934 +5935 +5936 +5937 +5938 +5939 +5940 +5941 +5942 +5943 +5944 +5945 +5946 +5947 +5948 +5949 +5950 +5951 +5952 +5953 +5954 +5955 +5956 +5957 +5958 +5959 +5960 +5961 +5962 +5963 +5964 +5965 +5966 +5967 +5968 +5969 +5970 +5971 +5972 +5973 +5974 +5975 +5976 +5977 +5978 +5979 +5980 +5981 +5982 +5983 +5984 +5985 +5986 +5987 +5988 +5989 +5990 +5991 +5992 +5993 +5994 +5995 +5996 +5997 +5998 +5999 +6000 +6001 +6002 +6003 +6004 +6005 +6006 +6007 +6008 +6009 +6010 +6011 +6012 +6013 +6014 +6015 +6016 +6017 +6018 +6019 +6020 +6021 +6022 +6023 +6024 +6025 +6026 +6027 +6028 +6029 +6030 +6031 +6032 +6033 +6034 +6035 +6036 +6037 +6038 +6039 +6040 +6041 +6042 +6043 +6044 +6045 +6046 +6047 +6048 +6049 +6050 +6051 +6052 +6053 +6054 +6055 +6056 +6057 +6058 +6059 +6060 +6061 +6062 +6063 +6064 +6065 +6066 +6067 +6068 +6069 +6070 +6071 +6072 +6073 +6074 +6075 +6076 +6077 +6078 +6079 +6080 +6081 +6082 +6083 +6084 +6085 +6086 +6087 +6088 +6089 +6090 +6091 +6092 +6093 +6094 +6095 +6096 +6097 +6098 +6099 +6100 +6101 +6102 +6103 +6104 +6105 +6106 +6107 +6108 +6109 +6110 +6111 +6112 +6113 +6114 +6115 +6116 +6117 +6118 +6119 +6120 +6121 +6122 +6123 +6124 +6125 +6126 +6127 +6128 +6129 +6130 +6131 +6132 +6133 +6134 +6135 +6136 +6137 +6138 +6139 +6140 +6141 +6142 +6143 +6144 +6145 +6146 +6147 +6148 +6149 +6150 +6151 +6152 +6153 +6154 +6155 +6156 +6157 +6158 +6159 +6160 +6161 +6162 +6163 +6164 +6165 +6166 +6167 +6168 +6169 +6170 +6171 +6172 +6173 +6174 +6175 +6176 +6177 +6178 +6179 +6180 +6181 +6182 +6183 +6184 +6185 +6186 +6187 +6188 +6189 +6190 +6191 +6192 +6193 +6194 +6195 +6196 +6197 +6198 +6199 +6200 +6201 +6202 +6203 +6204 +6205 +6206 +6207 +6208 +6209 +6210 +6211 +6212 +6213 +6214 +6215 +6216 +6217 +6218 +6219 +6220 +6221 +6222 +6223 +6224 +6225 +6226 +6227 +6228 +6229 +6230 +6231 +6232 +6233 +6234 +6235 +6236 +6237 +6238 +6239 +6240 +6241 +6242 +6243 +6244 +6245 +6246 +6247 +6248 +6249 +6250 +6251 +6252 +6253 +6254 +6255 +6256 +6257 +6258 +6259 +6260 +6261 +6262 +6263 +6264 +6265 +6266 +6267 +6268 +6269 +6270 +6271 +6272 +6273 +6274 +6275 +6276 +6277 +6278 +6279 +6280 +6281 +6282 +6283 +6284 +6285 +6286 +6287 +6288 +6289 +6290 +6291 +6292 +6293 +6294 +6295 +6296 +6297 +6298 +6299 +6300 +6301 +6302 +6303 +6304 +6305 +6306 +6307 +6308 +6309 +6310 +6311 +6312 +6313 +6314 +6315 +6316 +6317 +6318 +6319 +6320 +6321 +6322 +6323 +6324 +6325 +6326 +6327 +6328 +6329 +6330 +6331 +6332 +6333 +6334 +6335 +6336 +6337 +6338 +6339 +6340 +6341 +6342 +6343 +6344 +6345 +6346 +6347 +6348 +6349 +6350 +6351 +6352 +6353 +6354 +6355 +6356 +6357 +6358 +6359 +6360 +6361 +6362 +6363 +6364 +6365 +6366 +6367 +6368 +6369 +6370 +6371 +6372 +6373 +6374 +6375 +6376 +6377 +6378 +6379 +6380 +6381 +6382 +6383 +6384 +6385 +6386 +6387 +6388 +6389 +6390 +6391 +6392 +6393 +6394 +6395 +6396 +6397 +6398 +6399 +6400 +6401 +6402 +6403 +6404 +6405 +6406 +6407 +6408 +6409 +6410 +6411 +6412 +6413 +6414 +6415 +6416 +6417 +6418 +6419 +6420 +6421 +6422 +6423 +6424 +6425 +6426 +6427 +6428 +6429 +6430 +6431 +6432 +6433 +6434 +6435 +6436 +6437 +6438 +6439 +6440 +6441 +6442 +6443 +6444 +6445 +6446 +6447 +6448 +6449 +6450 +6451 +6452 +6453 +6454 +6455 +6456 +6457 +6458 +6459 +6460 +6461 +6462 +6463 +6464 +6465 +6466 +6467 +6468 +6469 +6470 +6471 +6472 +6473 +6474 +6475 +6476 +6477 +6478 +6479 +6480 +6481 +6482 +6483 +6484 +6485 +6486 +6487 +6488 +6489 +6490 +6491 +6492 +6493 +6494 +6495 +6496 +6497 +6498 +6499 +6500 +6501 +6502 +6503 +6504 +6505 +6506 +6507 +6508 +6509 +6510 +6511 +6512 +6513 +6514 +6515 +6516 +6517 +6518 +6519 +6520 +6521 +6522 +6523 +6524 +6525 +6526 +6527 +6528 +6529 +6530 +6531 +6532 +6533 +6534 +6535 +6536 +6537 +6538 +6539 +6540 +6541 +6542 +6543 +6544 +6545 +6546 +6547 +6548 +6549 +6550 +6551 +6552 +6553 +6554 +6555 +6556 +6557 +6558 +6559 +6560 +6561 +6562 +6563 +6564 +6565 +6566 +6567 +6568 +6569 +6570 +6571 +6572 +6573 +6574 +6575 +6576 +6577 +6578 +6579 +6580 +6581 +6582 +6583 +6584 +6585 +6586 +6587 +6588 +6589 +6590 +6591 +6592 +6593 +6594 +6595 +6596 +6597 +6598 +6599 +6600 +6601 +6602 +6603 +6604 +6605 +6606 +6607 +6608 +6609 +6610 +6611 +6612 +6613 +6614 +6615 +6616 +6617 +6618 +6619 +6620 +6621 +6622 +6623 +6624 +6625 +6626 +6627 +6628 +6629 +6630 +6631 +6632 +6633 +6634 +6635 +6636 +6637 +6638 +6639 +6640 +6641 +6642 +6643 +6644 +6645 +6646 +6647 +6648 +6649 +6650 +6651 +6652 +6653 +6654 +6655 +6656 +6657 +6658 +6659 +6660 +6661 +6662 +6663 +6664 +6665 +6666 +6667 +6668 +6669 +6670 +6671 +6672 +6673 +6674 +6675 +6676 +6677 +6678 +6679 +6680 +6681 +6682 +6683 +6684 +6685 +6686 +6687 +6688 +6689 +6690 +6691 +6692 +6693 +6694 +6695 +6696 +6697 +6698 +6699 +6700 +6701 +6702 +6703 +6704 +6705 +6706 +6707 +6708 +6709 +6710 +6711 +6712 +6713 +6714 +6715 +6716 +6717 +6718 +6719 +6720 +6721 +6722 +6723 +6724 +6725 +6726 +6727 +6728 +6729 +6730 +6731 +6732 +6733 +6734 +6735 +6736 +6737 +6738 +6739 +6740 +6741 +6742 +6743 +6744 +6745 +6746 +6747 +6748 +6749 +6750 +6751 +6752 +6753 +6754 +6755 +6756 +6757 +6758 +6759 +6760 +6761 +6762 +6763 +6764 +6765 +6766 +6767 +6768 +6769 +6770 +6771 +6772 +6773 +6774 +6775 +6776 +6777 +6778 +6779 +6780 +6781 +6782 +6783 +6784 +6785 +6786 +6787 +6788 +6789 +6790 +6791 +6792 +6793 +6794 +6795 +6796 +6797 +6798 +6799 +6800 +6801 +6802 +6803 +6804 +6805 +6806 +6807 +6808 +6809 +6810 +6811 +6812 +6813 +6814 +6815 +6816 +6817 +6818 +6819 +6820 +6821 +6822 +6823 +6824 +6825 +6826 +6827 +6828 +6829 +6830 +6831 +6832 +6833 +6834 +6835 +6836 +6837 +6838 +6839 +6840 +6841 +6842 +6843 +6844 +6845 +6846 +6847 +6848 +6849 +6850 +6851 +6852 +6853 +6854 +6855 +6856 +6857 +6858 +6859 +6860 +6861 +6862 +6863 +6864 +6865 +6866 +6867 +6868 +6869 +6870 +6871 +6872 +6873 +6874 +6875 +6876 +6877 +6878 +6879 +6880 +6881 +6882 +6883 +6884 +6885 +6886 +6887 +6888 +6889 +6890 +6891 +6892 +6893 +6894 +6895 +6896 +6897 +6898 +6899 +6900 +6901 +6902 +6903 +6904 +6905 +6906 +6907 +6908 +6909 +6910 +6911 +6912 +6913 +6914 +6915 +6916 +6917 +6918 +6919 +6920 +6921 +6922 +6923 +6924 +6925 +6926 +6927 +6928 +6929 +6930 +6931 +6932 +6933 +6934 +6935 +6936 +6937 +6938 +6939 +6940 +6941 +6942 +6943 +6944 +6945 +6946 +6947 +6948 +6949 +6950 +6951 +6952 +6953 +6954 +6955 +6956 +6957 +6958 +6959 +6960 +6961 +6962 +6963 +6964 +6965 +6966 +6967 +6968 +6969 +6970 +6971 +6972 +6973 +6974 +6975 +6976 +6977 +6978 +6979 +6980 +6981 +6982 +6983 +6984 +6985 +6986 +6987 +6988 +6989 +6990 +6991 +6992 +6993 +6994 +6995 +6996 +6997 +6998 +6999 +7000 +7001 +7002 +7003 +7004 +7005 +7006 +7007 +7008 +7009 +7010 +7011 +7012 +7013 +7014 +7015 +7016 +7017 +7018 +7019 +7020 +7021 +7022 +7023 +7024 +7025 +7026 +7027 +7028 +7029 +7030 +7031 +7032 +7033 +7034 +7035 +7036 +7037 +7038 +7039 +7040 +7041 +7042 +7043 +7044 +7045 +7046 +7047 +7048 +7049 +7050 +7051 +7052 +7053 +7054 +7055 +7056 +7057 +7058 +7059 +7060 +7061 +7062 +7063 +7064 +7065 +7066 +7067 +7068 +7069 +7070 +7071 +7072 +7073 +7074 +7075 +7076 +7077 +7078 +7079 +7080 +7081 +7082 +7083 +7084 +7085 +7086 +7087 +7088 +7089 +7090 +7091 +7092 +7093 +7094 +7095 +7096 +7097 +7098 +7099 +7100 +7101 +7102 +7103 +7104 +7105 +7106 +7107 +7108 +7109 +7110 +7111 +7112 +7113 +7114 +7115 +7116 +7117 +7118 +7119 +7120 +7121 +7122 +7123 +7124 +7125 +7126 +7127 +7128 +7129 +7130 +7131 +7132 +7133 +7134 +7135 +7136 +7137 +7138 +7139 +7140 +7141 +7142 +7143 +7144 +7145 +7146 +7147 +7148 +7149 +7150 +7151 +7152 +7153 +7154 +7155 +7156 +7157 +7158 +7159 +7160 +7161 +7162 +7163 +7164 +7165 +7166 +7167 +7168 +7169 +7170 +7171 +7172 +7173 +7174 +7175 +7176 +7177 +7178 +7179 +7180 +7181 +7182 +7183 +7184 +7185 +7186 +7187 +7188 +7189 +7190 +7191 +7192 +7193 +7194 +7195 +7196 +7197 +7198 +7199 +7200 +7201 +7202 +7203 +7204 +7205 +7206 +7207 +7208 +7209 +7210 +7211 +7212 +7213 +7214 +7215 +7216 +7217 +7218 +7219 +7220 +7221 +7222 +7223 +7224 +7225 +7226 +7227 +7228 +7229 +7230 +7231 +7232 +7233 +7234 +7235 +7236 +7237 +7238 +7239 +7240 +7241 +7242 +7243 +7244 +7245 +7246 +7247 +7248 +7249 +7250 +7251 +7252 +7253 +7254 +7255 +7256 +7257 +7258 +7259 +7260 +7261 +7262 +7263 +7264 +7265 +7266 +7267 +7268 +7269 +7270 +7271 +7272 +7273 +7274 +7275 +7276 +7277 +7278 +7279 +7280 +7281 +7282 +7283 +7284 +7285 +7286 +7287 +7288 +7289 +7290 +7291 +7292 +7293 +7294 +7295 +7296 +7297 +7298 +7299 +7300 +7301 +7302 +7303 +7304 +7305 +7306 +7307 +7308 +7309 +7310 +7311 +7312 +7313 +7314 +7315 +7316 +7317 +7318 +7319 +7320 +7321 +7322 +7323 +7324 +7325 +7326 +7327 +7328 +7329 +7330 +7331 +7332 +7333 +7334 +7335 +7336 +7337 +7338 +7339 +7340 +7341 +7342 +7343 +7344 +7345 +7346 +7347 +7348 +7349 +7350 +7351 +7352 +7353 +7354 +7355 +7356 +7357 +7358 +7359 +7360 +7361 +7362 +7363 +7364 +7365 +7366 +7367 +7368 +7369 +7370 +7371 +7372 +7373 +7374 +7375 +7376 +7377 +7378 +7379 +7380 +7381 +7382 +7383 +7384 +7385 +7386 +7387 +7388 +7389 +7390 +7391 +7392 +7393 +7394 +7395 +7396 +7397 +7398 +7399 +7400 +7401 +7402 +7403 +7404 +7405 +7406 +7407 +7408 +7409 +7410 +7411 +7412 +7413 +7414 +7415 +7416 +7417 +7418 +7419 +7420 +7421 +7422 +7423 +7424 +7425 +7426 +7427 +7428 +7429 +7430 +7431 +7432 +7433 +7434 +7435 +7436 +7437 +7438 +7439 +7440 +7441 +7442 +7443 +7444 +7445 +7446 +7447 +7448 +7449 +7450 +7451 +7452 +7453 +7454 +7455 +7456 +7457 +7458 +7459 +7460 +7461 +7462 +7463 +7464 +7465 +7466 +7467 +7468 +7469 +7470 +7471 +7472 +7473 +7474 +7475 +7476 +7477 +7478 +7479 +7480 +7481 +7482 +7483 +7484 +7485 +7486 +7487 +7488 +7489 +7490 +7491 +7492 +7493 +7494 +7495 +7496 +7497 +7498 +7499 +7500 +7501 +7502 +7503 +7504 +7505 +7506 +7507 +7508 +7509 +7510 +7511 +7512 +7513 +7514 +7515 +7516 +7517 +7518 +7519 +7520 +7521 +7522 +7523 +7524 +7525 +7526 +7527 +7528 +7529 +7530 +7531 +7532 +7533 +7534 +7535 +7536 +7537 +7538 +7539 +7540 +7541 +7542 +7543 +7544 +7545 +7546 +7547 +7548 +7549 +7550 +7551 +7552 +7553 +7554 +7555 +7556 +7557 +7558 +7559 +7560 +7561 +7562 +7563 +7564 +7565 +7566 +7567 +7568 +7569 +7570 +7571 +7572 +7573 +7574 +7575 +7576 +7577 +7578 +7579 +7580 +7581 +7582 +7583 +7584 +7585 +7586 +7587 +7588 +7589 +7590 +7591 +7592 +7593 +7594 +7595 +7596 +7597 +7598 +7599 +7600 +7601 +7602 +7603 +7604 +7605 +7606 +7607 +7608 +7609 +7610 +7611 +7612 +7613 +7614 +7615 +7616 +7617 +7618 +7619 +7620 +7621 +7622 +7623 +7624 +7625 +7626 +7627 +7628 +7629 +7630 +7631 +7632 +7633 +7634 +7635 +7636 +7637 +7638 +7639 +7640 +7641 +7642 +7643 +7644 +7645 +7646 +7647 +7648 +7649 +7650 +7651 +7652 +7653 +7654 +7655 +7656 +7657 +7658 +7659 +7660 +7661 +7662 +7663 +7664 +7665 +7666 +7667 +7668 +7669 +7670 +7671 +7672 +7673 +7674 +7675 +7676 +7677 +7678 +7679 +7680 +7681 +7682 +7683 +7684 +7685 +7686 +7687 +7688 +7689 +7690 +7691 +7692 +7693 +7694 +7695 +7696 +7697 +7698 +7699 +7700 +7701 +7702 +7703 +7704 +7705 +7706 +7707 +7708 +7709 +7710 +7711 +7712 +7713 +7714 +7715 +7716 +7717 +7718 +7719 +7720 +7721 +7722 +7723 +7724 +7725 +7726 +7727 +7728 +7729 +7730 +7731 +7732 +7733 +7734 +7735 +7736 +7737 +7738 +7739 +7740 +7741 +7742 +7743 +7744 +7745 +7746 +7747 +7748 +7749 +7750 +7751 +7752 +7753 +7754 +7755 +7756 +7757 +7758 +7759 +7760 +7761 +7762 +7763 +7764 +7765 +7766 +7767 +7768 +7769 +7770 +7771 +7772 +7773 +7774 +7775 +7776 +7777 +7778 +7779 +7780 +7781 +7782 +7783 +7784 +7785 +7786 +7787 +7788 +7789 +7790 +7791 +7792 +7793 +7794 +7795 +7796 +7797 +7798 +7799 +7800 +7801 +7802 +7803 +7804 +7805 +7806 +7807 +7808 +7809 +7810 +7811 +7812 +7813 +7814 +7815 +7816 +7817 +7818 +7819 +7820 +7821 +7822 +7823 +7824 +7825 +7826 +7827 +7828 +7829 +7830 +7831 +7832 +7833 +7834 +7835 +7836 +7837 +7838 +7839 +7840 +7841 +7842 +7843 +7844 +7845 +7846 +7847 +7848 +7849 +7850 +7851 +7852 +7853 +7854 +7855 +7856 +7857 +7858 +7859 +7860 +7861 +7862 +7863 +7864 +7865 +7866 +7867 +7868 +7869 +7870 +7871 +7872 +7873 +7874 +7875 +7876 +7877 +7878 +7879 +7880 +7881 +7882 +7883 +7884 +7885 +7886 +7887 +7888 +7889 +7890 +7891 +7892 +7893 +7894 +7895 +7896 +7897 +7898 +7899 +7900 +7901 +7902 +7903 +7904 +7905 +7906 +7907 +7908 +7909 +7910 +7911 +7912 +7913 +7914 +7915 +7916 +7917 +7918 +7919 +7920 +7921 +7922 +7923 +7924 +7925 +7926 +7927 +7928 +7929 +7930 +7931 +7932 +7933 +7934 +7935 +7936 +7937 +7938 +7939 +7940 +7941 +7942 +7943 +7944 +7945 +7946 +7947 +7948 +7949 +7950 +7951 +7952 +7953 +7954 +7955 +7956 +7957 +7958 +7959 +7960 +7961 +7962 +7963 +7964 +7965 +7966 +7967 +7968 +7969 +7970 +7971 +7972 +7973 +7974 +7975 +7976 +7977 +7978 +7979 +7980 +7981 +7982 +7983 +7984 +7985 +7986 +7987 +7988 +7989 +7990 +7991 +7992 +7993 +7994 +7995 +7996 +7997 +7998 +7999 +8000 +8001 +8002 +8003 +8004 +8005 +8006 +8007 +8008 +8009 +8010 +8011 +8012 +8013 +8014 +8015 +8016 +8017 +8018 +8019 +8020 +8021 +8022 +8023 +8024 +8025 +8026 +8027 +8028 +8029 +8030 +8031 +8032 +8033 +8034 +8035 +8036 +8037 +8038 +8039 +8040 +8041 +8042 +8043 +8044 +8045 +8046 +8047 +8048 +8049 +8050 +8051 +8052 +8053 +8054 +8055 +8056 +8057 +8058 +8059 +8060 +8061 +8062 +8063 +8064 +8065 +8066 +8067 +8068 +8069 +8070 +8071 +8072 +8073 +8074 +8075 +8076 +8077 +8078 +8079 +8080 +8081 +8082 +8083 +8084 +8085 +8086 +8087 +8088 +8089 +8090 +8091 +8092 +8093 +8094 +8095 +8096 +8097 +8098 +8099 +8100 +8101 +8102 +8103 +8104 +8105 +8106 +8107 +8108 +8109 +8110 +8111 +8112 +8113 +8114 +8115 +8116 +8117 +8118 +8119 +8120 +8121 +8122 +8123 +8124 +8125 +8126 +8127 +8128 +8129 +8130 +8131 +8132 +8133 +8134 +8135 +8136 +8137 +8138 +8139 +8140 +8141 +8142 +8143 +8144 +8145 +8146 +8147 +8148 +8149 +8150 +8151 +8152 +8153 +8154 +8155 +8156 +8157 +8158 +8159 +8160 +8161 +8162 +8163 +8164 +8165 +8166 +8167 +8168 +8169 +8170 +8171 +8172 +8173 +8174 +8175 +8176 +8177 +8178 +8179 +8180 +8181 +8182 +8183 +8184 +8185 +8186 +8187 +8188 +8189 +8190 +8191 +8192 +8193 +8194 +8195 +8196 +8197 +8198 +8199 +8200 +8201 +8202 +8203 +8204 +8205 +8206 +8207 +8208 +8209 +8210 +8211 +8212 +8213 +8214 +8215 +8216 +8217 +8218 +8219 +8220 +8221 +8222 +8223 +8224 +8225 +8226 +8227 +8228 +8229 +8230 +8231 +8232 +8233 +8234 +8235 +8236 +8237 +8238 +8239 +8240 +8241 +8242 +8243 +8244 +8245 +8246 +8247 +8248 +8249 +8250 +8251 +8252 +8253 +8254 +8255 +8256 +8257 +8258 +8259 +8260 +8261 +8262 +8263 +8264 +8265 +8266 +8267 +8268 +8269 +8270 +8271 +8272 +8273 +8274 +8275 +8276 +8277 +8278 +8279 +8280 +8281 +8282 +8283 +8284 +8285 +8286 +8287 +8288 +8289 +8290 +8291 +8292 +8293 +8294 +8295 +8296 +8297 +8298 +8299 +8300 +8301 +8302 +8303 +8304 +8305 +8306 +8307 +8308 +8309 +8310 +8311 +8312 +8313 +8314 +8315 +8316 +8317 +8318 +8319 +8320 +8321 +8322 +8323 +8324 +8325 +8326 +8327 +8328 +8329 +8330 +8331 +8332 +8333 +8334 +8335 +8336 +8337 +8338 +8339 +8340 +8341 +8342 +8343 +8344 +8345 +8346 +8347 +8348 +8349 +8350 +8351 +8352 +8353 +8354 +8355 +8356 +8357 +8358 +8359 +8360 +8361 +8362 +8363 +8364 +8365 +8366 +8367 +8368 +8369 +8370 +8371 +8372 +8373 +8374 +8375 +8376 +8377 +8378 +8379 +8380 +8381 +8382 +8383 +8384 +8385 +8386 +8387 +8388 +8389 +8390 +8391 +8392 +8393 +8394 +8395 +8396 +8397 +8398 +8399 +8400 +8401 +8402 +8403 +8404 +8405 +8406 +8407 +8408 +8409 +8410 +8411 +8412 +8413 +8414 +8415 +8416 +8417 +8418 +8419 +8420 +8421 +8422 +8423 +8424 +8425 +8426 +8427 +8428 +8429 +8430 +8431 +8432 +8433 +8434 +8435 +8436 +8437 +8438 +8439 +8440 +8441 +8442 +8443 +8444 +8445 +8446 +8447 +8448 +8449 +8450 +8451 +8452 +8453 +8454 +8455 +8456 +8457 +8458 +8459 +8460 +8461 +8462 +8463 +8464 +8465 +8466 +8467 +8468 +8469 +8470 +8471 +8472 +8473 +8474 +8475 +8476 +8477 +8478 +8479 +8480 +8481 +8482 +8483 +8484 +8485 +8486 +8487 +8488 +8489 +8490 +8491 +8492 +8493 +8494 +8495 +8496 +8497 +8498 +8499 +8500 +8501 +8502 +8503 +8504 +8505 +8506 +8507 +8508 +8509 +8510 +8511 +8512 +8513 +8514 +8515 +8516 +8517 +8518 +8519 +8520 +8521 +8522 +8523 +8524 +8525 +8526 +8527 +8528 +8529 +8530 +8531 +8532 +8533 +8534 +8535 +8536 +8537 +8538 +8539 +8540 +8541 +8542 +8543 +8544 +8545 +8546 +8547 +8548 +8549 +8550 +8551 +8552 +8553 +8554 +8555 +8556 +8557 +8558 +8559 +8560 +8561 +8562 +8563 +8564 +8565 +8566 +8567 +8568 +8569 +8570 +8571 +8572 +8573 +8574 +8575 +8576 +8577 +8578 +8579 +8580 +8581 +8582 +8583 +8584 +8585 +8586 +8587 +8588 +8589 +8590 +8591 +8592 +8593 +8594 +8595 +8596 +8597 +8598 +8599 +8600 +8601 +8602 +8603 +8604 +8605 +8606 +8607 +8608 +8609 +8610 +8611 +8612 +8613 +8614 +8615 +8616 +8617 +8618 +8619 +8620 +8621 +8622 +8623 +8624 +8625 +8626 +8627 +8628 +8629 +8630 +8631 +8632 +8633 +8634 +8635 +8636 +8637 +8638 +8639 +8640 +8641 +8642 +8643 +8644 +8645 +8646 +8647 +8648 +8649 +8650 +8651 +8652 +8653 +8654 +8655 +8656 +8657 +8658 +8659 +8660 +8661 +8662 +8663 +8664 +8665 +8666 +8667 +8668 +8669 +8670 +8671 +8672 +8673 +8674 +8675 +8676 +8677 +8678 +8679 +8680 +8681 +8682 +8683 +8684 +8685 +8686 +8687 +8688 +8689 +8690 +8691 +8692 +8693 +8694 +8695 +8696 +8697 +8698 +8699 +8700 +8701 +8702 +8703 +8704 +8705 +8706 +8707 +8708 +8709 +8710 +8711 +8712 +8713 +8714 +8715 +8716 +8717 +8718 +8719 +8720 +8721 +8722 +8723 +8724 +8725 +8726 +8727 +8728 +8729 +8730 +8731 +8732 +8733 +8734 +8735 +8736 +8737 +8738 +8739 +8740 +8741 +8742 +8743 +8744 +8745 +8746 +8747 +8748 +8749 +8750 +8751 +8752 +8753 +8754 +8755 +8756 +8757 +8758 +8759 +8760 +8761 +8762 +8763 +8764 +8765 +8766 +8767 +8768 +8769 +8770 +8771 +8772 +8773 +8774 +8775 +8776 +8777 +8778 +8779 +8780 +8781 +8782 +8783 +8784 +8785 +8786 +8787 +8788 +8789 +8790 +8791 +8792 +8793 +8794 +8795 +8796 +8797 +8798 +8799 +8800 +8801 +8802 +8803 +8804 +8805 +8806 +8807 +8808 +8809 +8810 +8811 +8812 +8813 +8814 +8815 +8816 +8817 +8818 +8819 +8820 +8821 +8822 +8823 +8824 +8825 +8826 +8827 +8828 +8829 +8830 +8831 +8832 +8833 +8834 +8835 +8836 +8837 +8838 +8839 +8840 +8841 +8842 +8843 +8844 +8845 +8846 +8847 +8848 +8849 +8850 +8851 +8852 +8853 +8854 +8855 +8856 +8857 +8858 +8859 +8860 +8861 +8862 +8863 +8864 +8865 +8866 +8867 +8868 +8869 +8870 +8871 +8872 +8873 +8874 +8875 +8876 +8877 +8878 +8879 +8880 +8881 +8882 +8883 +8884 +8885 +8886 +8887 +8888 +8889 +8890 +8891 +8892 +8893 +8894 +8895 +8896 +8897 +8898 +8899 +8900 +8901 +8902 +8903 +8904 +8905 +8906 +8907 +8908 +8909 +8910 +8911 +8912 +8913 +8914 +8915 +8916 +8917 +8918 +8919 +8920 +8921 +8922 +8923 +8924 +8925 +8926 +8927 +8928 +8929 +8930 +8931 +8932 +8933 +8934 +8935 +8936 +8937 +8938 +8939 +8940 +8941 +8942 +8943 +8944 +8945 +8946 +8947 +8948 +8949 +8950 +8951 +8952 +8953 +8954 +8955 +8956 +8957 +8958 +8959 +8960 +8961 +8962 +8963 +8964 +8965 +8966 +8967 +8968 +8969 +8970 +8971 +8972 +8973 +8974 +8975 +8976 +8977 +8978 +8979 +8980 +8981 +8982 +8983 +8984 +8985 +8986 +8987 +8988 +8989 +8990 +8991 +8992 +8993 +8994 +8995 +8996 +8997 +8998 +8999 +9000 +9001 +9002 +9003 +9004 +9005 +9006 +9007 +9008 +9009 +9010 +9011 +9012 +9013 +9014 +9015 +9016 +9017 +9018 +9019 +9020 +9021 +9022 +9023 +9024 +9025 +9026 +9027 +9028 +9029 +9030 +9031 +9032 +9033 +9034 +9035 +9036 +9037 +9038 +9039 +9040 +9041 +9042 +9043 +9044 +9045 +9046 +9047 +9048 +9049 +9050 +9051 +9052 +9053 +9054 +9055 +9056 +9057 +9058 +9059 +9060 +9061 +9062 +9063 +9064 +9065 +9066 +9067 +9068 +9069 +9070 +9071 +9072 +9073 +9074 +9075 +9076 +9077 +9078 +9079 +9080 +9081 +9082 +9083 +9084 +9085 +9086 +9087 +9088 +9089 +9090 +9091 +9092 +9093 +9094 +9095 +9096 +9097 +9098 +9099 +9100 +9101 +9102 +9103 +9104 +9105 +9106 +9107 +9108 +9109 +9110 +9111 +9112 +9113 +9114 +9115 +9116 +9117 +9118 +9119 +9120 +9121 +9122 +9123 +9124 +9125 +9126 +9127 +9128 +9129 +9130 +9131 +9132 +9133 +9134 +9135 +9136 +9137 +9138 +9139 +9140 +9141 +9142 +9143 +9144 +9145 +9146 +9147 +9148 +9149 +9150 +9151 +9152 +9153 +9154 +9155 +9156 +9157 +9158 +9159 +9160 +9161 +9162 +9163 +9164 +9165 +9166 +9167 +9168 +9169 +9170 +9171 +9172 +9173 +9174 +9175 +9176 +9177 +9178 +9179 +9180 +9181 +9182 +9183 +9184 +9185 +9186 +9187 +9188 +9189 +9190 +9191 +9192 +9193 +9194 +9195 +9196 +9197 +9198 +9199 +9200 +9201 +9202 +9203 +9204 +9205 +9206 +9207 +9208 +9209 +9210 +9211 +9212 +9213 +9214 +9215 +9216 +9217 +9218 +9219 +9220 +9221 +9222 +9223 +9224 +9225 +9226 +9227 +9228 +9229 +9230 +9231 +9232 +9233 +9234 +9235 +9236 +9237 +9238 +9239 +9240 +9241 +9242 +9243 +9244 +9245 +9246 +9247 +9248 +9249 +9250 +9251 +9252 +9253 +9254 +9255 +9256 +9257 +9258 +9259 +9260 +9261 +9262 +9263 +9264 +9265 +9266 +9267 +9268 +9269 +9270 +9271 +9272 +9273 +9274 +9275 +9276 +9277 +9278 +9279 +9280 +9281 +9282 +9283 +9284 +9285 +9286 +9287 +9288 +9289 +9290 +9291 +9292 +9293 +9294 +9295 +9296 +9297 +9298 +9299 +9300 +9301 +9302 +9303 +9304 +9305 +9306 +9307 +9308 +9309 +9310 +9311 +9312 +9313 +9314 +9315 +9316 +9317 +9318 +9319 +9320 +9321 +9322 +9323 +9324 +9325 +9326 +9327 +9328 +9329 +9330 +9331 +9332 +9333 +9334 +9335 +9336 +9337 +9338 +9339 +9340 +9341 +9342 +9343 +9344 +9345 +9346 +9347 +9348 +9349 +9350 +9351 +9352 +9353 +9354 +9355 +9356 +9357 +9358 +9359 +9360 +9361 +9362 +9363 +9364 +9365 +9366 +9367 +9368 +9369 +9370 +9371 +9372 +9373 +9374 +9375 +9376 +9377 +9378 +9379 +9380 +9381 +9382 +9383 +9384 +9385 +9386 +9387 +9388 +9389 +9390 +9391 +9392 +9393 +9394 +9395 +9396 +9397 +9398 +9399 +9400 +9401 +9402 +9403 +9404 +9405 +9406 +9407 +9408 +9409 +9410 +9411 +9412 +9413 +9414 +9415 +9416 +9417 +9418 +9419 +9420 +9421 +9422 +9423 +9424 +9425 +9426 +9427 +9428 +9429 +9430 +9431 +9432 +9433 +9434 +9435 +9436 +9437 +9438 +9439 +9440 +9441 +9442 +9443 +9444 +9445 +9446 +9447 +9448 +9449 +9450 +9451 +9452 +9453 +9454 +9455 +9456 +9457 +9458 +9459 +9460 +9461 +9462 +9463 +9464 +9465 +9466 +9467 +9468 +9469 +9470 +9471 +9472 +9473 +9474 +9475 +9476 +9477 +9478 +9479 +9480 +9481 +9482 +9483 +9484 +9485 +9486 +9487 +9488 +9489 +9490 +9491 +9492 +9493 +9494 +9495 +9496 +9497 +9498 +9499 +9500 +9501 +9502 +9503 +9504 +9505 +9506 +9507 +9508 +9509 +9510 +9511 +9512 +9513 +9514 +9515 +9516 +9517 +9518 +9519 +9520 +9521 +9522 +9523 +9524 +9525 +9526 +9527 +9528 +9529 +9530 +9531 +9532 +9533 +9534 +9535 +9536 +9537 +9538 +9539 +9540 +9541 +9542 +9543 +9544 +9545 +9546 +9547 +9548 +9549 +9550 +9551 +9552 +9553 +9554 +9555 +9556 +9557 +9558 +9559 +9560 +9561 +9562 +9563 +9564 +9565 +9566 +9567 +9568 +9569 +9570 +9571 +9572 +9573 +9574 +9575 +9576 +9577 +9578 +9579 +9580 +9581 +9582 +9583 +9584 +9585 +9586 +9587 +9588 +9589 +9590 +9591 +9592 +9593 +9594 +9595 +9596 +9597 +9598 +9599 +9600 +9601 +9602 +9603 +9604 +9605 +9606 +9607 +9608 +9609 +9610 +9611 +9612 +9613 +9614 +9615 +9616 +9617 +9618 +9619 +9620 +9621 +9622 +9623 +9624 +9625 +9626 +9627 +9628 +9629 +9630 +9631 +9632 +9633 +9634 +9635 +9636 +9637 +9638 +9639 +9640 +9641 +9642 +9643 +9644 +9645 +9646 +9647 +9648 +9649 +9650 +9651 +9652 +9653 +9654 +9655 +9656 +9657 +9658 +9659 +9660 +9661 +9662 +9663 +9664 +9665 +9666 +9667 +9668 +9669 +9670 +9671 +9672 +9673 +9674 +9675 +9676 +9677 +9678 +9679 +9680 +9681 +9682 +9683 +9684 +9685 +9686 +9687 +9688 +9689 +9690 +9691 +9692 +9693 +9694 +9695 +9696 +9697 +9698 +9699 +9700 +9701 +9702 +9703 +9704 +9705 +9706 +9707 +9708 +9709 +9710 +9711 +9712 +9713 +9714 +9715 +9716 +9717 +9718 +9719 +9720 +9721 +9722 +9723 +9724 +9725 +9726 +9727 +9728 +9729 +9730 +9731 +9732 +9733 +9734 +9735 +9736 +9737 +9738 +9739 +9740 +9741 +9742 +9743 +9744 +9745 +9746 +9747 +9748 +9749 +9750 +9751 +9752 +9753 +9754 +9755 +9756 +9757 +9758 +9759 +9760 +9761 +9762 +9763 +9764 +9765 +9766 +9767 +9768 +9769 +9770 +9771 +9772 +9773 +9774 +9775 +9776 +9777 +9778 +9779 +9780 +9781 +9782 +9783 +9784 +9785 +9786 +9787 +9788 +9789 +9790 +9791 +9792 +9793 +9794 +9795 +9796 +9797 +9798 +9799 +9800 +9801 +9802 +9803 +9804 +9805 +9806 +9807 +9808 +9809 +9810 +9811 +9812 +9813 +9814 +9815 +9816 +9817 +9818 +9819 +9820 +9821 +9822 +9823 +9824 +9825 +9826 +9827 +9828 +9829 +9830 +9831 +9832 +9833 +9834 +9835 +9836 +9837 +9838 +9839 +9840 +9841 +9842 +9843 +9844 +9845 +9846 +9847 +9848 +9849 +9850 +9851 +9852 +9853 +9854 +9855 +9856 +9857 +9858 +9859 +9860 +9861 +9862 +9863 +9864 +9865 +9866 +9867 +9868 +9869 +9870 +9871 +9872 +9873 +9874 +9875 +9876 +9877 +9878 +9879 +9880 +9881 +9882 +9883 +9884 +9885 +9886 +9887 +9888 +9889 +9890 +9891 +9892 +9893 +9894 +9895 +9896 +9897 +9898 +9899 +9900 +9901 +9902 +9903 +9904 +9905 +9906 +9907 +9908 +9909 +9910 +9911 +9912 +9913 +9914 +9915 +9916 +9917 +9918 +9919 +9920 +9921 +9922 +9923 +9924 +9925 +9926 +9927 +9928 +9929 +9930 +9931 +9932 +9933 +9934 +9935 +9936 +9937 +9938 +9939 +9940 +9941 +9942 +9943 +9944 +9945 +9946 +9947 +9948 +9949 +9950 +9951 +9952 +9953 +9954 +9955 +9956 +9957 +9958 +9959 +9960 +9961 +9962 +9963 +9964 +9965 +9966 +9967 +9968 +9969 +9970 +9971 +9972 +9973 +9974 +9975 +9976 +9977 +9978 +9979 +9980 +9981 +9982 +9983 +9984 +9985 +9986 +9987 +9988 +9989 +9990 +9991 +9992 +9993 +9994 +9995 +9996 +9997 +9998 +9999 +10000 diff --git a/mysql-test/std_data/bug30435_5k.txt b/mysql-test/std_data/bug30435_5k.txt new file mode 100644 index 00000000000..7d1714969fc --- /dev/null +++ b/mysql-test/std_data/bug30435_5k.txt @@ -0,0 +1,5000 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741 +742 +743 +744 +745 +746 +747 +748 +749 +750 +751 +752 +753 +754 +755 +756 +757 +758 +759 +760 +761 +762 +763 +764 +765 +766 +767 +768 +769 +770 +771 +772 +773 +774 +775 +776 +777 +778 +779 +780 +781 +782 +783 +784 +785 +786 +787 +788 +789 +790 +791 +792 +793 +794 +795 +796 +797 +798 +799 +800 +801 +802 +803 +804 +805 +806 +807 +808 +809 +810 +811 +812 +813 +814 +815 +816 +817 +818 +819 +820 +821 +822 +823 +824 +825 +826 +827 +828 +829 +830 +831 +832 +833 +834 +835 +836 +837 +838 +839 +840 +841 +842 +843 +844 +845 +846 +847 +848 +849 +850 +851 +852 +853 +854 +855 +856 +857 +858 +859 +860 +861 +862 +863 +864 +865 +866 +867 +868 +869 +870 +871 +872 +873 +874 +875 +876 +877 +878 +879 +880 +881 +882 +883 +884 +885 +886 +887 +888 +889 +890 +891 +892 +893 +894 +895 +896 +897 +898 +899 +900 +901 +902 +903 +904 +905 +906 +907 +908 +909 +910 +911 +912 +913 +914 +915 +916 +917 +918 +919 +920 +921 +922 +923 +924 +925 +926 +927 +928 +929 +930 +931 +932 +933 +934 +935 +936 +937 +938 +939 +940 +941 +942 +943 +944 +945 +946 +947 +948 +949 +950 +951 +952 +953 +954 +955 +956 +957 +958 +959 +960 +961 +962 +963 +964 +965 +966 +967 +968 +969 +970 +971 +972 +973 +974 +975 +976 +977 +978 +979 +980 +981 +982 +983 +984 +985 +986 +987 +988 +989 +990 +991 +992 +993 +994 +995 +996 +997 +998 +999 +1000 +1001 +1002 +1003 +1004 +1005 +1006 +1007 +1008 +1009 +1010 +1011 +1012 +1013 +1014 +1015 +1016 +1017 +1018 +1019 +1020 +1021 +1022 +1023 +1024 +1025 +1026 +1027 +1028 +1029 +1030 +1031 +1032 +1033 +1034 +1035 +1036 +1037 +1038 +1039 +1040 +1041 +1042 +1043 +1044 +1045 +1046 +1047 +1048 +1049 +1050 +1051 +1052 +1053 +1054 +1055 +1056 +1057 +1058 +1059 +1060 +1061 +1062 +1063 +1064 +1065 +1066 +1067 +1068 +1069 +1070 +1071 +1072 +1073 +1074 +1075 +1076 +1077 +1078 +1079 +1080 +1081 +1082 +1083 +1084 +1085 +1086 +1087 +1088 +1089 +1090 +1091 +1092 +1093 +1094 +1095 +1096 +1097 +1098 +1099 +1100 +1101 +1102 +1103 +1104 +1105 +1106 +1107 +1108 +1109 +1110 +1111 +1112 +1113 +1114 +1115 +1116 +1117 +1118 +1119 +1120 +1121 +1122 +1123 +1124 +1125 +1126 +1127 +1128 +1129 +1130 +1131 +1132 +1133 +1134 +1135 +1136 +1137 +1138 +1139 +1140 +1141 +1142 +1143 +1144 +1145 +1146 +1147 +1148 +1149 +1150 +1151 +1152 +1153 +1154 +1155 +1156 +1157 +1158 +1159 +1160 +1161 +1162 +1163 +1164 +1165 +1166 +1167 +1168 +1169 +1170 +1171 +1172 +1173 +1174 +1175 +1176 +1177 +1178 +1179 +1180 +1181 +1182 +1183 +1184 +1185 +1186 +1187 +1188 +1189 +1190 +1191 +1192 +1193 +1194 +1195 +1196 +1197 +1198 +1199 +1200 +1201 +1202 +1203 +1204 +1205 +1206 +1207 +1208 +1209 +1210 +1211 +1212 +1213 +1214 +1215 +1216 +1217 +1218 +1219 +1220 +1221 +1222 +1223 +1224 +1225 +1226 +1227 +1228 +1229 +1230 +1231 +1232 +1233 +1234 +1235 +1236 +1237 +1238 +1239 +1240 +1241 +1242 +1243 +1244 +1245 +1246 +1247 +1248 +1249 +1250 +1251 +1252 +1253 +1254 +1255 +1256 +1257 +1258 +1259 +1260 +1261 +1262 +1263 +1264 +1265 +1266 +1267 +1268 +1269 +1270 +1271 +1272 +1273 +1274 +1275 +1276 +1277 +1278 +1279 +1280 +1281 +1282 +1283 +1284 +1285 +1286 +1287 +1288 +1289 +1290 +1291 +1292 +1293 +1294 +1295 +1296 +1297 +1298 +1299 +1300 +1301 +1302 +1303 +1304 +1305 +1306 +1307 +1308 +1309 +1310 +1311 +1312 +1313 +1314 +1315 +1316 +1317 +1318 +1319 +1320 +1321 +1322 +1323 +1324 +1325 +1326 +1327 +1328 +1329 +1330 +1331 +1332 +1333 +1334 +1335 +1336 +1337 +1338 +1339 +1340 +1341 +1342 +1343 +1344 +1345 +1346 +1347 +1348 +1349 +1350 +1351 +1352 +1353 +1354 +1355 +1356 +1357 +1358 +1359 +1360 +1361 +1362 +1363 +1364 +1365 +1366 +1367 +1368 +1369 +1370 +1371 +1372 +1373 +1374 +1375 +1376 +1377 +1378 +1379 +1380 +1381 +1382 +1383 +1384 +1385 +1386 +1387 +1388 +1389 +1390 +1391 +1392 +1393 +1394 +1395 +1396 +1397 +1398 +1399 +1400 +1401 +1402 +1403 +1404 +1405 +1406 +1407 +1408 +1409 +1410 +1411 +1412 +1413 +1414 +1415 +1416 +1417 +1418 +1419 +1420 +1421 +1422 +1423 +1424 +1425 +1426 +1427 +1428 +1429 +1430 +1431 +1432 +1433 +1434 +1435 +1436 +1437 +1438 +1439 +1440 +1441 +1442 +1443 +1444 +1445 +1446 +1447 +1448 +1449 +1450 +1451 +1452 +1453 +1454 +1455 +1456 +1457 +1458 +1459 +1460 +1461 +1462 +1463 +1464 +1465 +1466 +1467 +1468 +1469 +1470 +1471 +1472 +1473 +1474 +1475 +1476 +1477 +1478 +1479 +1480 +1481 +1482 +1483 +1484 +1485 +1486 +1487 +1488 +1489 +1490 +1491 +1492 +1493 +1494 +1495 +1496 +1497 +1498 +1499 +1500 +1501 +1502 +1503 +1504 +1505 +1506 +1507 +1508 +1509 +1510 +1511 +1512 +1513 +1514 +1515 +1516 +1517 +1518 +1519 +1520 +1521 +1522 +1523 +1524 +1525 +1526 +1527 +1528 +1529 +1530 +1531 +1532 +1533 +1534 +1535 +1536 +1537 +1538 +1539 +1540 +1541 +1542 +1543 +1544 +1545 +1546 +1547 +1548 +1549 +1550 +1551 +1552 +1553 +1554 +1555 +1556 +1557 +1558 +1559 +1560 +1561 +1562 +1563 +1564 +1565 +1566 +1567 +1568 +1569 +1570 +1571 +1572 +1573 +1574 +1575 +1576 +1577 +1578 +1579 +1580 +1581 +1582 +1583 +1584 +1585 +1586 +1587 +1588 +1589 +1590 +1591 +1592 +1593 +1594 +1595 +1596 +1597 +1598 +1599 +1600 +1601 +1602 +1603 +1604 +1605 +1606 +1607 +1608 +1609 +1610 +1611 +1612 +1613 +1614 +1615 +1616 +1617 +1618 +1619 +1620 +1621 +1622 +1623 +1624 +1625 +1626 +1627 +1628 +1629 +1630 +1631 +1632 +1633 +1634 +1635 +1636 +1637 +1638 +1639 +1640 +1641 +1642 +1643 +1644 +1645 +1646 +1647 +1648 +1649 +1650 +1651 +1652 +1653 +1654 +1655 +1656 +1657 +1658 +1659 +1660 +1661 +1662 +1663 +1664 +1665 +1666 +1667 +1668 +1669 +1670 +1671 +1672 +1673 +1674 +1675 +1676 +1677 +1678 +1679 +1680 +1681 +1682 +1683 +1684 +1685 +1686 +1687 +1688 +1689 +1690 +1691 +1692 +1693 +1694 +1695 +1696 +1697 +1698 +1699 +1700 +1701 +1702 +1703 +1704 +1705 +1706 +1707 +1708 +1709 +1710 +1711 +1712 +1713 +1714 +1715 +1716 +1717 +1718 +1719 +1720 +1721 +1722 +1723 +1724 +1725 +1726 +1727 +1728 +1729 +1730 +1731 +1732 +1733 +1734 +1735 +1736 +1737 +1738 +1739 +1740 +1741 +1742 +1743 +1744 +1745 +1746 +1747 +1748 +1749 +1750 +1751 +1752 +1753 +1754 +1755 +1756 +1757 +1758 +1759 +1760 +1761 +1762 +1763 +1764 +1765 +1766 +1767 +1768 +1769 +1770 +1771 +1772 +1773 +1774 +1775 +1776 +1777 +1778 +1779 +1780 +1781 +1782 +1783 +1784 +1785 +1786 +1787 +1788 +1789 +1790 +1791 +1792 +1793 +1794 +1795 +1796 +1797 +1798 +1799 +1800 +1801 +1802 +1803 +1804 +1805 +1806 +1807 +1808 +1809 +1810 +1811 +1812 +1813 +1814 +1815 +1816 +1817 +1818 +1819 +1820 +1821 +1822 +1823 +1824 +1825 +1826 +1827 +1828 +1829 +1830 +1831 +1832 +1833 +1834 +1835 +1836 +1837 +1838 +1839 +1840 +1841 +1842 +1843 +1844 +1845 +1846 +1847 +1848 +1849 +1850 +1851 +1852 +1853 +1854 +1855 +1856 +1857 +1858 +1859 +1860 +1861 +1862 +1863 +1864 +1865 +1866 +1867 +1868 +1869 +1870 +1871 +1872 +1873 +1874 +1875 +1876 +1877 +1878 +1879 +1880 +1881 +1882 +1883 +1884 +1885 +1886 +1887 +1888 +1889 +1890 +1891 +1892 +1893 +1894 +1895 +1896 +1897 +1898 +1899 +1900 +1901 +1902 +1903 +1904 +1905 +1906 +1907 +1908 +1909 +1910 +1911 +1912 +1913 +1914 +1915 +1916 +1917 +1918 +1919 +1920 +1921 +1922 +1923 +1924 +1925 +1926 +1927 +1928 +1929 +1930 +1931 +1932 +1933 +1934 +1935 +1936 +1937 +1938 +1939 +1940 +1941 +1942 +1943 +1944 +1945 +1946 +1947 +1948 +1949 +1950 +1951 +1952 +1953 +1954 +1955 +1956 +1957 +1958 +1959 +1960 +1961 +1962 +1963 +1964 +1965 +1966 +1967 +1968 +1969 +1970 +1971 +1972 +1973 +1974 +1975 +1976 +1977 +1978 +1979 +1980 +1981 +1982 +1983 +1984 +1985 +1986 +1987 +1988 +1989 +1990 +1991 +1992 +1993 +1994 +1995 +1996 +1997 +1998 +1999 +2000 +2001 +2002 +2003 +2004 +2005 +2006 +2007 +2008 +2009 +2010 +2011 +2012 +2013 +2014 +2015 +2016 +2017 +2018 +2019 +2020 +2021 +2022 +2023 +2024 +2025 +2026 +2027 +2028 +2029 +2030 +2031 +2032 +2033 +2034 +2035 +2036 +2037 +2038 +2039 +2040 +2041 +2042 +2043 +2044 +2045 +2046 +2047 +2048 +2049 +2050 +2051 +2052 +2053 +2054 +2055 +2056 +2057 +2058 +2059 +2060 +2061 +2062 +2063 +2064 +2065 +2066 +2067 +2068 +2069 +2070 +2071 +2072 +2073 +2074 +2075 +2076 +2077 +2078 +2079 +2080 +2081 +2082 +2083 +2084 +2085 +2086 +2087 +2088 +2089 +2090 +2091 +2092 +2093 +2094 +2095 +2096 +2097 +2098 +2099 +2100 +2101 +2102 +2103 +2104 +2105 +2106 +2107 +2108 +2109 +2110 +2111 +2112 +2113 +2114 +2115 +2116 +2117 +2118 +2119 +2120 +2121 +2122 +2123 +2124 +2125 +2126 +2127 +2128 +2129 +2130 +2131 +2132 +2133 +2134 +2135 +2136 +2137 +2138 +2139 +2140 +2141 +2142 +2143 +2144 +2145 +2146 +2147 +2148 +2149 +2150 +2151 +2152 +2153 +2154 +2155 +2156 +2157 +2158 +2159 +2160 +2161 +2162 +2163 +2164 +2165 +2166 +2167 +2168 +2169 +2170 +2171 +2172 +2173 +2174 +2175 +2176 +2177 +2178 +2179 +2180 +2181 +2182 +2183 +2184 +2185 +2186 +2187 +2188 +2189 +2190 +2191 +2192 +2193 +2194 +2195 +2196 +2197 +2198 +2199 +2200 +2201 +2202 +2203 +2204 +2205 +2206 +2207 +2208 +2209 +2210 +2211 +2212 +2213 +2214 +2215 +2216 +2217 +2218 +2219 +2220 +2221 +2222 +2223 +2224 +2225 +2226 +2227 +2228 +2229 +2230 +2231 +2232 +2233 +2234 +2235 +2236 +2237 +2238 +2239 +2240 +2241 +2242 +2243 +2244 +2245 +2246 +2247 +2248 +2249 +2250 +2251 +2252 +2253 +2254 +2255 +2256 +2257 +2258 +2259 +2260 +2261 +2262 +2263 +2264 +2265 +2266 +2267 +2268 +2269 +2270 +2271 +2272 +2273 +2274 +2275 +2276 +2277 +2278 +2279 +2280 +2281 +2282 +2283 +2284 +2285 +2286 +2287 +2288 +2289 +2290 +2291 +2292 +2293 +2294 +2295 +2296 +2297 +2298 +2299 +2300 +2301 +2302 +2303 +2304 +2305 +2306 +2307 +2308 +2309 +2310 +2311 +2312 +2313 +2314 +2315 +2316 +2317 +2318 +2319 +2320 +2321 +2322 +2323 +2324 +2325 +2326 +2327 +2328 +2329 +2330 +2331 +2332 +2333 +2334 +2335 +2336 +2337 +2338 +2339 +2340 +2341 +2342 +2343 +2344 +2345 +2346 +2347 +2348 +2349 +2350 +2351 +2352 +2353 +2354 +2355 +2356 +2357 +2358 +2359 +2360 +2361 +2362 +2363 +2364 +2365 +2366 +2367 +2368 +2369 +2370 +2371 +2372 +2373 +2374 +2375 +2376 +2377 +2378 +2379 +2380 +2381 +2382 +2383 +2384 +2385 +2386 +2387 +2388 +2389 +2390 +2391 +2392 +2393 +2394 +2395 +2396 +2397 +2398 +2399 +2400 +2401 +2402 +2403 +2404 +2405 +2406 +2407 +2408 +2409 +2410 +2411 +2412 +2413 +2414 +2415 +2416 +2417 +2418 +2419 +2420 +2421 +2422 +2423 +2424 +2425 +2426 +2427 +2428 +2429 +2430 +2431 +2432 +2433 +2434 +2435 +2436 +2437 +2438 +2439 +2440 +2441 +2442 +2443 +2444 +2445 +2446 +2447 +2448 +2449 +2450 +2451 +2452 +2453 +2454 +2455 +2456 +2457 +2458 +2459 +2460 +2461 +2462 +2463 +2464 +2465 +2466 +2467 +2468 +2469 +2470 +2471 +2472 +2473 +2474 +2475 +2476 +2477 +2478 +2479 +2480 +2481 +2482 +2483 +2484 +2485 +2486 +2487 +2488 +2489 +2490 +2491 +2492 +2493 +2494 +2495 +2496 +2497 +2498 +2499 +2500 +2501 +2502 +2503 +2504 +2505 +2506 +2507 +2508 +2509 +2510 +2511 +2512 +2513 +2514 +2515 +2516 +2517 +2518 +2519 +2520 +2521 +2522 +2523 +2524 +2525 +2526 +2527 +2528 +2529 +2530 +2531 +2532 +2533 +2534 +2535 +2536 +2537 +2538 +2539 +2540 +2541 +2542 +2543 +2544 +2545 +2546 +2547 +2548 +2549 +2550 +2551 +2552 +2553 +2554 +2555 +2556 +2557 +2558 +2559 +2560 +2561 +2562 +2563 +2564 +2565 +2566 +2567 +2568 +2569 +2570 +2571 +2572 +2573 +2574 +2575 +2576 +2577 +2578 +2579 +2580 +2581 +2582 +2583 +2584 +2585 +2586 +2587 +2588 +2589 +2590 +2591 +2592 +2593 +2594 +2595 +2596 +2597 +2598 +2599 +2600 +2601 +2602 +2603 +2604 +2605 +2606 +2607 +2608 +2609 +2610 +2611 +2612 +2613 +2614 +2615 +2616 +2617 +2618 +2619 +2620 +2621 +2622 +2623 +2624 +2625 +2626 +2627 +2628 +2629 +2630 +2631 +2632 +2633 +2634 +2635 +2636 +2637 +2638 +2639 +2640 +2641 +2642 +2643 +2644 +2645 +2646 +2647 +2648 +2649 +2650 +2651 +2652 +2653 +2654 +2655 +2656 +2657 +2658 +2659 +2660 +2661 +2662 +2663 +2664 +2665 +2666 +2667 +2668 +2669 +2670 +2671 +2672 +2673 +2674 +2675 +2676 +2677 +2678 +2679 +2680 +2681 +2682 +2683 +2684 +2685 +2686 +2687 +2688 +2689 +2690 +2691 +2692 +2693 +2694 +2695 +2696 +2697 +2698 +2699 +2700 +2701 +2702 +2703 +2704 +2705 +2706 +2707 +2708 +2709 +2710 +2711 +2712 +2713 +2714 +2715 +2716 +2717 +2718 +2719 +2720 +2721 +2722 +2723 +2724 +2725 +2726 +2727 +2728 +2729 +2730 +2731 +2732 +2733 +2734 +2735 +2736 +2737 +2738 +2739 +2740 +2741 +2742 +2743 +2744 +2745 +2746 +2747 +2748 +2749 +2750 +2751 +2752 +2753 +2754 +2755 +2756 +2757 +2758 +2759 +2760 +2761 +2762 +2763 +2764 +2765 +2766 +2767 +2768 +2769 +2770 +2771 +2772 +2773 +2774 +2775 +2776 +2777 +2778 +2779 +2780 +2781 +2782 +2783 +2784 +2785 +2786 +2787 +2788 +2789 +2790 +2791 +2792 +2793 +2794 +2795 +2796 +2797 +2798 +2799 +2800 +2801 +2802 +2803 +2804 +2805 +2806 +2807 +2808 +2809 +2810 +2811 +2812 +2813 +2814 +2815 +2816 +2817 +2818 +2819 +2820 +2821 +2822 +2823 +2824 +2825 +2826 +2827 +2828 +2829 +2830 +2831 +2832 +2833 +2834 +2835 +2836 +2837 +2838 +2839 +2840 +2841 +2842 +2843 +2844 +2845 +2846 +2847 +2848 +2849 +2850 +2851 +2852 +2853 +2854 +2855 +2856 +2857 +2858 +2859 +2860 +2861 +2862 +2863 +2864 +2865 +2866 +2867 +2868 +2869 +2870 +2871 +2872 +2873 +2874 +2875 +2876 +2877 +2878 +2879 +2880 +2881 +2882 +2883 +2884 +2885 +2886 +2887 +2888 +2889 +2890 +2891 +2892 +2893 +2894 +2895 +2896 +2897 +2898 +2899 +2900 +2901 +2902 +2903 +2904 +2905 +2906 +2907 +2908 +2909 +2910 +2911 +2912 +2913 +2914 +2915 +2916 +2917 +2918 +2919 +2920 +2921 +2922 +2923 +2924 +2925 +2926 +2927 +2928 +2929 +2930 +2931 +2932 +2933 +2934 +2935 +2936 +2937 +2938 +2939 +2940 +2941 +2942 +2943 +2944 +2945 +2946 +2947 +2948 +2949 +2950 +2951 +2952 +2953 +2954 +2955 +2956 +2957 +2958 +2959 +2960 +2961 +2962 +2963 +2964 +2965 +2966 +2967 +2968 +2969 +2970 +2971 +2972 +2973 +2974 +2975 +2976 +2977 +2978 +2979 +2980 +2981 +2982 +2983 +2984 +2985 +2986 +2987 +2988 +2989 +2990 +2991 +2992 +2993 +2994 +2995 +2996 +2997 +2998 +2999 +3000 +3001 +3002 +3003 +3004 +3005 +3006 +3007 +3008 +3009 +3010 +3011 +3012 +3013 +3014 +3015 +3016 +3017 +3018 +3019 +3020 +3021 +3022 +3023 +3024 +3025 +3026 +3027 +3028 +3029 +3030 +3031 +3032 +3033 +3034 +3035 +3036 +3037 +3038 +3039 +3040 +3041 +3042 +3043 +3044 +3045 +3046 +3047 +3048 +3049 +3050 +3051 +3052 +3053 +3054 +3055 +3056 +3057 +3058 +3059 +3060 +3061 +3062 +3063 +3064 +3065 +3066 +3067 +3068 +3069 +3070 +3071 +3072 +3073 +3074 +3075 +3076 +3077 +3078 +3079 +3080 +3081 +3082 +3083 +3084 +3085 +3086 +3087 +3088 +3089 +3090 +3091 +3092 +3093 +3094 +3095 +3096 +3097 +3098 +3099 +3100 +3101 +3102 +3103 +3104 +3105 +3106 +3107 +3108 +3109 +3110 +3111 +3112 +3113 +3114 +3115 +3116 +3117 +3118 +3119 +3120 +3121 +3122 +3123 +3124 +3125 +3126 +3127 +3128 +3129 +3130 +3131 +3132 +3133 +3134 +3135 +3136 +3137 +3138 +3139 +3140 +3141 +3142 +3143 +3144 +3145 +3146 +3147 +3148 +3149 +3150 +3151 +3152 +3153 +3154 +3155 +3156 +3157 +3158 +3159 +3160 +3161 +3162 +3163 +3164 +3165 +3166 +3167 +3168 +3169 +3170 +3171 +3172 +3173 +3174 +3175 +3176 +3177 +3178 +3179 +3180 +3181 +3182 +3183 +3184 +3185 +3186 +3187 +3188 +3189 +3190 +3191 +3192 +3193 +3194 +3195 +3196 +3197 +3198 +3199 +3200 +3201 +3202 +3203 +3204 +3205 +3206 +3207 +3208 +3209 +3210 +3211 +3212 +3213 +3214 +3215 +3216 +3217 +3218 +3219 +3220 +3221 +3222 +3223 +3224 +3225 +3226 +3227 +3228 +3229 +3230 +3231 +3232 +3233 +3234 +3235 +3236 +3237 +3238 +3239 +3240 +3241 +3242 +3243 +3244 +3245 +3246 +3247 +3248 +3249 +3250 +3251 +3252 +3253 +3254 +3255 +3256 +3257 +3258 +3259 +3260 +3261 +3262 +3263 +3264 +3265 +3266 +3267 +3268 +3269 +3270 +3271 +3272 +3273 +3274 +3275 +3276 +3277 +3278 +3279 +3280 +3281 +3282 +3283 +3284 +3285 +3286 +3287 +3288 +3289 +3290 +3291 +3292 +3293 +3294 +3295 +3296 +3297 +3298 +3299 +3300 +3301 +3302 +3303 +3304 +3305 +3306 +3307 +3308 +3309 +3310 +3311 +3312 +3313 +3314 +3315 +3316 +3317 +3318 +3319 +3320 +3321 +3322 +3323 +3324 +3325 +3326 +3327 +3328 +3329 +3330 +3331 +3332 +3333 +3334 +3335 +3336 +3337 +3338 +3339 +3340 +3341 +3342 +3343 +3344 +3345 +3346 +3347 +3348 +3349 +3350 +3351 +3352 +3353 +3354 +3355 +3356 +3357 +3358 +3359 +3360 +3361 +3362 +3363 +3364 +3365 +3366 +3367 +3368 +3369 +3370 +3371 +3372 +3373 +3374 +3375 +3376 +3377 +3378 +3379 +3380 +3381 +3382 +3383 +3384 +3385 +3386 +3387 +3388 +3389 +3390 +3391 +3392 +3393 +3394 +3395 +3396 +3397 +3398 +3399 +3400 +3401 +3402 +3403 +3404 +3405 +3406 +3407 +3408 +3409 +3410 +3411 +3412 +3413 +3414 +3415 +3416 +3417 +3418 +3419 +3420 +3421 +3422 +3423 +3424 +3425 +3426 +3427 +3428 +3429 +3430 +3431 +3432 +3433 +3434 +3435 +3436 +3437 +3438 +3439 +3440 +3441 +3442 +3443 +3444 +3445 +3446 +3447 +3448 +3449 +3450 +3451 +3452 +3453 +3454 +3455 +3456 +3457 +3458 +3459 +3460 +3461 +3462 +3463 +3464 +3465 +3466 +3467 +3468 +3469 +3470 +3471 +3472 +3473 +3474 +3475 +3476 +3477 +3478 +3479 +3480 +3481 +3482 +3483 +3484 +3485 +3486 +3487 +3488 +3489 +3490 +3491 +3492 +3493 +3494 +3495 +3496 +3497 +3498 +3499 +3500 +3501 +3502 +3503 +3504 +3505 +3506 +3507 +3508 +3509 +3510 +3511 +3512 +3513 +3514 +3515 +3516 +3517 +3518 +3519 +3520 +3521 +3522 +3523 +3524 +3525 +3526 +3527 +3528 +3529 +3530 +3531 +3532 +3533 +3534 +3535 +3536 +3537 +3538 +3539 +3540 +3541 +3542 +3543 +3544 +3545 +3546 +3547 +3548 +3549 +3550 +3551 +3552 +3553 +3554 +3555 +3556 +3557 +3558 +3559 +3560 +3561 +3562 +3563 +3564 +3565 +3566 +3567 +3568 +3569 +3570 +3571 +3572 +3573 +3574 +3575 +3576 +3577 +3578 +3579 +3580 +3581 +3582 +3583 +3584 +3585 +3586 +3587 +3588 +3589 +3590 +3591 +3592 +3593 +3594 +3595 +3596 +3597 +3598 +3599 +3600 +3601 +3602 +3603 +3604 +3605 +3606 +3607 +3608 +3609 +3610 +3611 +3612 +3613 +3614 +3615 +3616 +3617 +3618 +3619 +3620 +3621 +3622 +3623 +3624 +3625 +3626 +3627 +3628 +3629 +3630 +3631 +3632 +3633 +3634 +3635 +3636 +3637 +3638 +3639 +3640 +3641 +3642 +3643 +3644 +3645 +3646 +3647 +3648 +3649 +3650 +3651 +3652 +3653 +3654 +3655 +3656 +3657 +3658 +3659 +3660 +3661 +3662 +3663 +3664 +3665 +3666 +3667 +3668 +3669 +3670 +3671 +3672 +3673 +3674 +3675 +3676 +3677 +3678 +3679 +3680 +3681 +3682 +3683 +3684 +3685 +3686 +3687 +3688 +3689 +3690 +3691 +3692 +3693 +3694 +3695 +3696 +3697 +3698 +3699 +3700 +3701 +3702 +3703 +3704 +3705 +3706 +3707 +3708 +3709 +3710 +3711 +3712 +3713 +3714 +3715 +3716 +3717 +3718 +3719 +3720 +3721 +3722 +3723 +3724 +3725 +3726 +3727 +3728 +3729 +3730 +3731 +3732 +3733 +3734 +3735 +3736 +3737 +3738 +3739 +3740 +3741 +3742 +3743 +3744 +3745 +3746 +3747 +3748 +3749 +3750 +3751 +3752 +3753 +3754 +3755 +3756 +3757 +3758 +3759 +3760 +3761 +3762 +3763 +3764 +3765 +3766 +3767 +3768 +3769 +3770 +3771 +3772 +3773 +3774 +3775 +3776 +3777 +3778 +3779 +3780 +3781 +3782 +3783 +3784 +3785 +3786 +3787 +3788 +3789 +3790 +3791 +3792 +3793 +3794 +3795 +3796 +3797 +3798 +3799 +3800 +3801 +3802 +3803 +3804 +3805 +3806 +3807 +3808 +3809 +3810 +3811 +3812 +3813 +3814 +3815 +3816 +3817 +3818 +3819 +3820 +3821 +3822 +3823 +3824 +3825 +3826 +3827 +3828 +3829 +3830 +3831 +3832 +3833 +3834 +3835 +3836 +3837 +3838 +3839 +3840 +3841 +3842 +3843 +3844 +3845 +3846 +3847 +3848 +3849 +3850 +3851 +3852 +3853 +3854 +3855 +3856 +3857 +3858 +3859 +3860 +3861 +3862 +3863 +3864 +3865 +3866 +3867 +3868 +3869 +3870 +3871 +3872 +3873 +3874 +3875 +3876 +3877 +3878 +3879 +3880 +3881 +3882 +3883 +3884 +3885 +3886 +3887 +3888 +3889 +3890 +3891 +3892 +3893 +3894 +3895 +3896 +3897 +3898 +3899 +3900 +3901 +3902 +3903 +3904 +3905 +3906 +3907 +3908 +3909 +3910 +3911 +3912 +3913 +3914 +3915 +3916 +3917 +3918 +3919 +3920 +3921 +3922 +3923 +3924 +3925 +3926 +3927 +3928 +3929 +3930 +3931 +3932 +3933 +3934 +3935 +3936 +3937 +3938 +3939 +3940 +3941 +3942 +3943 +3944 +3945 +3946 +3947 +3948 +3949 +3950 +3951 +3952 +3953 +3954 +3955 +3956 +3957 +3958 +3959 +3960 +3961 +3962 +3963 +3964 +3965 +3966 +3967 +3968 +3969 +3970 +3971 +3972 +3973 +3974 +3975 +3976 +3977 +3978 +3979 +3980 +3981 +3982 +3983 +3984 +3985 +3986 +3987 +3988 +3989 +3990 +3991 +3992 +3993 +3994 +3995 +3996 +3997 +3998 +3999 +4000 +4001 +4002 +4003 +4004 +4005 +4006 +4007 +4008 +4009 +4010 +4011 +4012 +4013 +4014 +4015 +4016 +4017 +4018 +4019 +4020 +4021 +4022 +4023 +4024 +4025 +4026 +4027 +4028 +4029 +4030 +4031 +4032 +4033 +4034 +4035 +4036 +4037 +4038 +4039 +4040 +4041 +4042 +4043 +4044 +4045 +4046 +4047 +4048 +4049 +4050 +4051 +4052 +4053 +4054 +4055 +4056 +4057 +4058 +4059 +4060 +4061 +4062 +4063 +4064 +4065 +4066 +4067 +4068 +4069 +4070 +4071 +4072 +4073 +4074 +4075 +4076 +4077 +4078 +4079 +4080 +4081 +4082 +4083 +4084 +4085 +4086 +4087 +4088 +4089 +4090 +4091 +4092 +4093 +4094 +4095 +4096 +4097 +4098 +4099 +4100 +4101 +4102 +4103 +4104 +4105 +4106 +4107 +4108 +4109 +4110 +4111 +4112 +4113 +4114 +4115 +4116 +4117 +4118 +4119 +4120 +4121 +4122 +4123 +4124 +4125 +4126 +4127 +4128 +4129 +4130 +4131 +4132 +4133 +4134 +4135 +4136 +4137 +4138 +4139 +4140 +4141 +4142 +4143 +4144 +4145 +4146 +4147 +4148 +4149 +4150 +4151 +4152 +4153 +4154 +4155 +4156 +4157 +4158 +4159 +4160 +4161 +4162 +4163 +4164 +4165 +4166 +4167 +4168 +4169 +4170 +4171 +4172 +4173 +4174 +4175 +4176 +4177 +4178 +4179 +4180 +4181 +4182 +4183 +4184 +4185 +4186 +4187 +4188 +4189 +4190 +4191 +4192 +4193 +4194 +4195 +4196 +4197 +4198 +4199 +4200 +4201 +4202 +4203 +4204 +4205 +4206 +4207 +4208 +4209 +4210 +4211 +4212 +4213 +4214 +4215 +4216 +4217 +4218 +4219 +4220 +4221 +4222 +4223 +4224 +4225 +4226 +4227 +4228 +4229 +4230 +4231 +4232 +4233 +4234 +4235 +4236 +4237 +4238 +4239 +4240 +4241 +4242 +4243 +4244 +4245 +4246 +4247 +4248 +4249 +4250 +4251 +4252 +4253 +4254 +4255 +4256 +4257 +4258 +4259 +4260 +4261 +4262 +4263 +4264 +4265 +4266 +4267 +4268 +4269 +4270 +4271 +4272 +4273 +4274 +4275 +4276 +4277 +4278 +4279 +4280 +4281 +4282 +4283 +4284 +4285 +4286 +4287 +4288 +4289 +4290 +4291 +4292 +4293 +4294 +4295 +4296 +4297 +4298 +4299 +4300 +4301 +4302 +4303 +4304 +4305 +4306 +4307 +4308 +4309 +4310 +4311 +4312 +4313 +4314 +4315 +4316 +4317 +4318 +4319 +4320 +4321 +4322 +4323 +4324 +4325 +4326 +4327 +4328 +4329 +4330 +4331 +4332 +4333 +4334 +4335 +4336 +4337 +4338 +4339 +4340 +4341 +4342 +4343 +4344 +4345 +4346 +4347 +4348 +4349 +4350 +4351 +4352 +4353 +4354 +4355 +4356 +4357 +4358 +4359 +4360 +4361 +4362 +4363 +4364 +4365 +4366 +4367 +4368 +4369 +4370 +4371 +4372 +4373 +4374 +4375 +4376 +4377 +4378 +4379 +4380 +4381 +4382 +4383 +4384 +4385 +4386 +4387 +4388 +4389 +4390 +4391 +4392 +4393 +4394 +4395 +4396 +4397 +4398 +4399 +4400 +4401 +4402 +4403 +4404 +4405 +4406 +4407 +4408 +4409 +4410 +4411 +4412 +4413 +4414 +4415 +4416 +4417 +4418 +4419 +4420 +4421 +4422 +4423 +4424 +4425 +4426 +4427 +4428 +4429 +4430 +4431 +4432 +4433 +4434 +4435 +4436 +4437 +4438 +4439 +4440 +4441 +4442 +4443 +4444 +4445 +4446 +4447 +4448 +4449 +4450 +4451 +4452 +4453 +4454 +4455 +4456 +4457 +4458 +4459 +4460 +4461 +4462 +4463 +4464 +4465 +4466 +4467 +4468 +4469 +4470 +4471 +4472 +4473 +4474 +4475 +4476 +4477 +4478 +4479 +4480 +4481 +4482 +4483 +4484 +4485 +4486 +4487 +4488 +4489 +4490 +4491 +4492 +4493 +4494 +4495 +4496 +4497 +4498 +4499 +4500 +4501 +4502 +4503 +4504 +4505 +4506 +4507 +4508 +4509 +4510 +4511 +4512 +4513 +4514 +4515 +4516 +4517 +4518 +4519 +4520 +4521 +4522 +4523 +4524 +4525 +4526 +4527 +4528 +4529 +4530 +4531 +4532 +4533 +4534 +4535 +4536 +4537 +4538 +4539 +4540 +4541 +4542 +4543 +4544 +4545 +4546 +4547 +4548 +4549 +4550 +4551 +4552 +4553 +4554 +4555 +4556 +4557 +4558 +4559 +4560 +4561 +4562 +4563 +4564 +4565 +4566 +4567 +4568 +4569 +4570 +4571 +4572 +4573 +4574 +4575 +4576 +4577 +4578 +4579 +4580 +4581 +4582 +4583 +4584 +4585 +4586 +4587 +4588 +4589 +4590 +4591 +4592 +4593 +4594 +4595 +4596 +4597 +4598 +4599 +4600 +4601 +4602 +4603 +4604 +4605 +4606 +4607 +4608 +4609 +4610 +4611 +4612 +4613 +4614 +4615 +4616 +4617 +4618 +4619 +4620 +4621 +4622 +4623 +4624 +4625 +4626 +4627 +4628 +4629 +4630 +4631 +4632 +4633 +4634 +4635 +4636 +4637 +4638 +4639 +4640 +4641 +4642 +4643 +4644 +4645 +4646 +4647 +4648 +4649 +4650 +4651 +4652 +4653 +4654 +4655 +4656 +4657 +4658 +4659 +4660 +4661 +4662 +4663 +4664 +4665 +4666 +4667 +4668 +4669 +4670 +4671 +4672 +4673 +4674 +4675 +4676 +4677 +4678 +4679 +4680 +4681 +4682 +4683 +4684 +4685 +4686 +4687 +4688 +4689 +4690 +4691 +4692 +4693 +4694 +4695 +4696 +4697 +4698 +4699 +4700 +4701 +4702 +4703 +4704 +4705 +4706 +4707 +4708 +4709 +4710 +4711 +4712 +4713 +4714 +4715 +4716 +4717 +4718 +4719 +4720 +4721 +4722 +4723 +4724 +4725 +4726 +4727 +4728 +4729 +4730 +4731 +4732 +4733 +4734 +4735 +4736 +4737 +4738 +4739 +4740 +4741 +4742 +4743 +4744 +4745 +4746 +4747 +4748 +4749 +4750 +4751 +4752 +4753 +4754 +4755 +4756 +4757 +4758 +4759 +4760 +4761 +4762 +4763 +4764 +4765 +4766 +4767 +4768 +4769 +4770 +4771 +4772 +4773 +4774 +4775 +4776 +4777 +4778 +4779 +4780 +4781 +4782 +4783 +4784 +4785 +4786 +4787 +4788 +4789 +4790 +4791 +4792 +4793 +4794 +4795 +4796 +4797 +4798 +4799 +4800 +4801 +4802 +4803 +4804 +4805 +4806 +4807 +4808 +4809 +4810 +4811 +4812 +4813 +4814 +4815 +4816 +4817 +4818 +4819 +4820 +4821 +4822 +4823 +4824 +4825 +4826 +4827 +4828 +4829 +4830 +4831 +4832 +4833 +4834 +4835 +4836 +4837 +4838 +4839 +4840 +4841 +4842 +4843 +4844 +4845 +4846 +4847 +4848 +4849 +4850 +4851 +4852 +4853 +4854 +4855 +4856 +4857 +4858 +4859 +4860 +4861 +4862 +4863 +4864 +4865 +4866 +4867 +4868 +4869 +4870 +4871 +4872 +4873 +4874 +4875 +4876 +4877 +4878 +4879 +4880 +4881 +4882 +4883 +4884 +4885 +4886 +4887 +4888 +4889 +4890 +4891 +4892 +4893 +4894 +4895 +4896 +4897 +4898 +4899 +4900 +4901 +4902 +4903 +4904 +4905 +4906 +4907 +4908 +4909 +4910 +4911 +4912 +4913 +4914 +4915 +4916 +4917 +4918 +4919 +4920 +4921 +4922 +4923 +4924 +4925 +4926 +4927 +4928 +4929 +4930 +4931 +4932 +4933 +4934 +4935 +4936 +4937 +4938 +4939 +4940 +4941 +4942 +4943 +4944 +4945 +4946 +4947 +4948 +4949 +4950 +4951 +4952 +4953 +4954 +4955 +4956 +4957 +4958 +4959 +4960 +4961 +4962 +4963 +4964 +4965 +4966 +4967 +4968 +4969 +4970 +4971 +4972 +4973 +4974 +4975 +4976 +4977 +4978 +4979 +4980 +4981 +4982 +4983 +4984 +4985 +4986 +4987 +4988 +4989 +4990 +4991 +4992 +4993 +4994 +4995 +4996 +4997 +4998 +4999 +5000 diff --git a/mysql-test/suite/binlog/r/binlog_base64_flag.result b/mysql-test/suite/binlog/r/binlog_base64_flag.result new file mode 100644 index 00000000000..aa801346d9f --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_base64_flag.result @@ -0,0 +1,60 @@ +==== Test BUG#32407 ==== +select * from t1; +a +1 +1 +==== Test BINLOG statement w/o FD event ==== +BINLOG ' +SVtYRxMBAAAAKQAAADQBAAAAABAAAAAAAAAABHRlc3QAAnQxAAEDAAE= +SVtYRxcBAAAAIgAAAFYBAAAQABAAAAAAAAEAAf/+AgAAAA== +'; +ERROR HY000: The BINLOG statement of type `Table_map` was not preceded by a format description BINLOG statement. +select * from t1; +a +1 +1 +==== Test BINLOG statement with FD event ==== +BINLOG ' +ODdYRw8BAAAAZgAAAGoAAAABAAQANS4xLjIzLXJjLWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAA4N1hHEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC +'; +BINLOG ' +TFtYRxMBAAAAKQAAAH8BAAAAABAAAAAAAAAABHRlc3QAAnQxAAEDAAE= +TFtYRxcBAAAAIgAAAKEBAAAQABAAAAAAAAEAAf/+AwAAAA== +'; +select * from t1; +a +1 +1 +3 +==== Test --base64-output=never on a binlog with row events ==== +/*!40019 SET @@session.max_insert_delayed_threads=0*/; +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; +DELIMITER /*!*/; +# at 4 +#ROLLBACK/*!*/; +# at 102 +#use test/*!*/; +SET TIMESTAMP=1196959712/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; +SET @@session.sql_mode=0/*!*/; +/*!\C latin1 *//*!*/; +SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; +create table t1 (a int) engine= myisam/*!*/; +# at 203 +==== Test non-matching FD event and Row event ==== +BINLOG ' +4CdYRw8BAAAAYgAAAGYAAAAAAAQANS4xLjE1LW5kYi02LjEuMjQtZGVidWctbG9nAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAADgJ1hHEzgNAAgAEgAEBAQEEgAATwAEGggICAg= +'; +BINLOG ' +Dl1YRxMBAAAAKQAAADQBAAAAABAAAAAAAAAABHRlc3QAAnQxAAEDAAE= +Dl1YRxcBAAAAIgAAAFYBAAAQABAAAAAAAAEAAf/+BQAAAA== +'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use +select * from t1; +a +1 +1 +3 +drop table t1; diff --git a/mysql-test/suite/binlog/r/binlog_innodb.result b/mysql-test/suite/binlog/r/binlog_innodb.result index 34538eb5215..896d8f734fc 100644 --- a/mysql-test/suite/binlog/r/binlog_innodb.result +++ b/mysql-test/suite/binlog/r/binlog_innodb.result @@ -66,6 +66,7 @@ COMMIT; show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=INNODB +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; BEGIN diff --git a/mysql-test/suite/binlog/r/binlog_killed_simulate.result b/mysql-test/suite/binlog/r/binlog_killed_simulate.result index f6a5ddade51..c0087316420 100644 --- a/mysql-test/suite/binlog/r/binlog_killed_simulate.result +++ b/mysql-test/suite/binlog/r/binlog_killed_simulate.result @@ -18,8 +18,8 @@ load data infile '../std_data_ln/rpl_loaddata.dat' into table t2 /* will be "kil ERROR 70100: Query execution was interrupted show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Begin_load_query # # ;file_id=1;block_len=12 -master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/rpl_loaddata.dat' into table t2 /* will be "killed" in the middle */ ;file_id=1 +master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=12 +master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/rpl_loaddata.dat' into table t2 /* will be "killed" in the middle */ ;file_id=# select (@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog")) is not null; diff --git a/mysql-test/suite/binlog/r/binlog_multi_engine.result b/mysql-test/suite/binlog/r/binlog_multi_engine.result index 67c3412ec15..13227c5ecb1 100644 --- a/mysql-test/suite/binlog/r/binlog_multi_engine.result +++ b/mysql-test/suite/binlog/r/binlog_multi_engine.result @@ -18,8 +18,12 @@ TRUNCATE t1n; show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2) +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2) +master-bin.000001 # Query # # use `test`; COMMIT +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c +master-bin.000001 # Query # # use `test`; COMMIT master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2) master-bin.000001 # Query # # use `test`; UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f @@ -49,8 +53,12 @@ TRUNCATE t1n; show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2) +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2) +master-bin.000001 # Query # # use `test`; COMMIT +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c +master-bin.000001 # Query # # use `test`; COMMIT master-bin.000001 # Query # # use `test`; TRUNCATE t1m master-bin.000001 # Query # # use `test`; TRUNCATE t1b master-bin.000001 # Query # # BEGIN diff --git a/mysql-test/suite/binlog/r/binlog_old_versions.result b/mysql-test/suite/binlog/r/binlog_old_versions.result new file mode 100644 index 00000000000..a514f9278a6 --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_old_versions.result @@ -0,0 +1,61 @@ +DROP TABLE IF EXISTS t1, t2, t3; +==== Read modern binlog (version 5.1.23) ==== +SELECT * FROM t1 ORDER BY a; +a b +0 last_insert_id +1 one +3 last stm in trx: next event should be xid +4 four +674568 random +SELECT * FROM t2 ORDER BY a; +a b +3 first stm in trx +SELECT COUNT(*) FROM t3; +COUNT(*) +17920 +DROP TABLE t1, t2, t3; +==== Read binlog from version 5.1.17 ==== +SELECT * FROM t1 ORDER BY a; +a b +0 last_insert_id +1 one +3 last stm in trx: next event should be xid +4 four +764247 random +SELECT * FROM t2 ORDER BY a; +a b +3 first stm in trx +SELECT COUNT(*) FROM t3; +COUNT(*) +17920 +DROP TABLE t1, t2, t3; +==== Read binlog from alcatel tree (mysql-5.1-wl2325-5.0-drop6) ==== +SELECT * FROM t1 ORDER BY a; +a b +0 last_insert_id +1 one +3 last stm in trx: next event should be xid +4 four +781729 random +SELECT * FROM t2 ORDER BY a; +a b +3 first stm in trx +SELECT COUNT(*) FROM t3; +COUNT(*) +17920 +DROP TABLE t1, t2, t3; +==== Read binlog from ndb tree (mysql-5.1-telco-6.1) ==== +SELECT * FROM t1 ORDER BY a; +a b +0 last_insert_id +1 one +3 last stm in trx: next event should be xid +4 four +703356 random +SELECT * FROM t2 ORDER BY a; +a b +3 first stm in trx +SELECT COUNT(*) FROM t3; +COUNT(*) +17920 +DROP TABLE t1, t2, t3; diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result index fd91f65bbb5..6c5c149d48e 100644 --- a/mysql-test/suite/binlog/r/binlog_row_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result @@ -1099,9 +1099,11 @@ master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # use `test`; drop table t1 master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t2` ( `a` int(11) DEFAULT NULL ) +master-bin.000001 # Query # # use `test`; COMMIT master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t3` ( `a` int(11) DEFAULT NULL ) @@ -1124,9 +1126,11 @@ master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # use `test`; drop table t1 master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t2` ( `a` int(11) DEFAULT NULL ) +master-bin.000001 # Query # # use `test`; COMMIT master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t3` ( `a` int(11) DEFAULT NULL ) diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result index f69d5717a1f..63bab2c1169 100644 --- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result @@ -113,6 +113,7 @@ insert into t1 values(9); insert into t2 select * from t1; show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ @@ -126,6 +127,7 @@ begin; insert into t2 select * from t1; show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ @@ -135,6 +137,7 @@ insert into t1 values(11); commit; show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ @@ -260,10 +263,12 @@ master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; alter table t2 engine=MyISAM +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ @@ -366,6 +371,7 @@ master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t2 master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (a int, b int, primary key (a)) engine=innodb master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; TRUNCATE table t2 master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Table_map # # table_id: # (test.t1) @@ -383,6 +389,7 @@ master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; TRUNCATE table t2 master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Table_map # # table_id: # (test.t1) @@ -408,17 +415,16 @@ is not null; is not null 1 select -@a like "%#%error_code=0%ROLLBACK/*!*/;%ROLLBACK /* added by mysqlbinlog */;%", +@a like "%#%error_code=0%ROLLBACK\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" OR +@a like "%#%error_code=0%ROLLBACK\r\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%", @a not like "%#%error_code=%error_code=%"; -@a like "%#%error_code=0%ROLLBACK/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" @a not like "%#%error_code=%error_code=%" +@a like "%#%error_code=0%ROLLBACK\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" OR +@a like "%#%error_code=0%ROLLBACK\r\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" @a not like "%#%error_code=%error_code=%" 1 1 drop table t1, t2; create temporary table tt (a int unique); create table ti (a int) engine=innodb; reset master; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 106 begin; insert into ti values (1); insert into ti values (2) ; @@ -429,9 +435,259 @@ Warning 1196 Some non-transactional changed tables couldn't be rolled back select count(*) from tt /* 2 */; count(*) 2 -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 395 +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Table_map # # table_id: # (test.ti) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map # # table_id: # (test.ti) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; ROLLBACK +select count(*) from ti /* zero */; +count(*) +0 +insert into ti select * from tt; +select * from ti /* that is what slave would miss - a bug */; +a +1 +2 +delete from ti; +delete from tt where a=1; +reset master; +begin; +insert into ti values (1); +insert into ti values (2) /* to make the dup error in the following */; +insert into tt select * from ti /* one affected and error */; +ERROR 23000: Duplicate entry '2' for key 'a' +rollback; +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +select count(*) from ti /* zero */; +count(*) +0 +insert into ti select * from tt; +select * from tt /* that is what otherwise slave missed - the bug */; +a +1 +2 +drop table ti, tt; +drop function if exists bug27417; +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, PRIMARY KEY (a)); +create function bug27417(n int) +RETURNS int(11) +begin +insert into t1 values (null); +return n; +end| +reset master; +insert into t2 values (bug27417(1)); +insert into t2 select bug27417(2); +reset master; +insert into t2 values (bug27417(2)); +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +/* only (!) with fixes for #23333 will show there is the query */; +select count(*) from t1 /* must be 3 */; +count(*) +3 +reset master; +select count(*) from t2; +count(*) +2 +delete from t2 where a=bug27417(3); +select count(*) from t2 /* nothing got deleted */; +count(*) +2 +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +/* the query must be in regardless of #23333 */; +select count(*) from t1 /* must be 5 */; +count(*) +5 +delete t2 from t2 where t2.a=bug27417(100) /* must not affect t2 */; +affected rows: 0 +select count(*) from t1 /* must be 7 */; +count(*) +7 +drop table t1,t2; +CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM; +CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB; +CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique) ENGINE=MyISAM; +CREATE TABLE t4 (a int, PRIMARY KEY (a), b int unique) ENGINE=Innodb; +CREATE TABLE t5 (a int, PRIMARY KEY (a)) ENGINE=InnoDB; +insert into t2 values (1); +reset master; +insert into t2 values (bug27417(1)); +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; ROLLBACK +/* the output must denote there is the query */; +select count(*) from t1 /* must be 1 */; +count(*) +1 +delete from t1; +delete from t2; +insert into t2 values (2); +reset master; +insert into t2 select bug27417(1) union select bug27417(2); +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; ROLLBACK +/* the output must denote there is the query */; +select count(*) from t1 /* must be 2 */; +count(*) +2 +delete from t1; +insert into t3 values (1,1),(2,3),(3,4); +reset master; +update t3 set b=b+bug27417(1); +ERROR 23000: Duplicate entry '4' for key 'b' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Table_map # # table_id: # (test.t3) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Update_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +/* the output must denote there is the query */; +select count(*) from t1 /* must be 2 */; +count(*) +2 +delete from t3; +delete from t4; +insert into t3 values (1,1); +insert into t4 values (1,1),(2,2); +reset master; +UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */; +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t4) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; ROLLBACK +/* the output must denote there is the query */; +select count(*) from t1 /* must be 4 */; +count(*) +4 +delete from t1; +delete from t3; +delete from t4; +insert into t3 values (1,1),(2,2); +insert into t4 values (1,1),(2,2); +reset master; +UPDATE t3,t4 SET t3.a=t4.a + bug27417(1); +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +select count(*) from t1 /* must be 1 */; +count(*) +2 +drop table t4; +delete from t1; +delete from t2; +delete from t3; +insert into t2 values (1); +insert into t3 values (1,1); +create trigger trg_del before delete on t2 for each row +insert into t3 values (bug27417(1), 2); +reset master; +delete from t2; +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Table_map # # table_id: # (test.t3) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; ROLLBACK +/* the output must denote there is the query */; +select count(*) from t1 /* must be 1 */; +count(*) +1 +drop trigger trg_del; +delete from t1; +delete from t2; +delete from t5; +create trigger trg_del_t2 after delete on t2 for each row +insert into t1 values (1); +insert into t2 values (2),(3); +insert into t5 values (1),(2); +reset master; +delete t2.* from t2,t5 where t2.a=t5.a + 1; +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Delete_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; ROLLBACK +/* the output must denote there is the query */; +select count(*) from t1 /* must be 1 */; +count(*) +1 +delete from t1; +create table t4 (a int default 0, b int primary key) engine=innodb; +insert into t4 values (0, 17); +reset master; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2); +ERROR 23000: Duplicate entry '17' for key 'PRIMARY' +select * from t4; +a b +0 17 +select count(*) from t1 /* must be 2 */; +count(*) +2 +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t4) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; ROLLBACK +/* the output must denote there is the query */; +drop trigger trg_del_t2; +drop table t1,t2,t3,t4,t5; +drop function bug27417; +end of tests +create temporary table tt (a int unique); +create table ti (a int) engine=innodb; +reset master; +begin; +insert into ti values (1); +insert into ti values (2) ; +insert into tt select * from ti; +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +select count(*) from tt /* 2 */; +count(*) +2 show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; BEGIN @@ -451,18 +707,12 @@ a delete from ti; delete from tt where a=1; reset master; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 106 begin; insert into ti values (1); insert into ti values (2) /* to make the dup error in the following */; insert into tt select * from ti /* one affected and error */; ERROR 23000: Duplicate entry '2' for key 'a' rollback; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 106 show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info select count(*) from ti /* zero */; @@ -529,6 +779,7 @@ insert into t2 values (bug27417(1)); ERROR 23000: Duplicate entry '1' for key 'PRIMARY' show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Intvar # # INSERT_ID=1 master-bin.000001 # Query # # use `test`; insert into t2 values (bug27417(1)) master-bin.000001 # Query # # use `test`; ROLLBACK @@ -543,6 +794,7 @@ insert into t2 select bug27417(1) union select bug27417(2); ERROR 23000: Duplicate entry '2' for key 'PRIMARY' show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Intvar # # INSERT_ID=2 master-bin.000001 # Query # # use `test`; insert into t2 select bug27417(1) union select bug27417(2) master-bin.000001 # Query # # use `test`; ROLLBACK @@ -570,6 +822,7 @@ UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */; ERROR 23000: Duplicate entry '2' for key 'PRIMARY' show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Intvar # # INSERT_ID=6 master-bin.000001 # Query # # use `test`; UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */ master-bin.000001 # Query # # use `test`; ROLLBACK @@ -600,6 +853,7 @@ delete from t2; ERROR 23000: Duplicate entry '1' for key 'PRIMARY' show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Intvar # # INSERT_ID=9 master-bin.000001 # Query # # use `test`; delete from t2 master-bin.000001 # Query # # use `test`; ROLLBACK @@ -619,6 +873,7 @@ delete t2.* from t2,t5 where t2.a=t5.a + 1; ERROR 23000: Duplicate entry '1' for key 'PRIMARY' show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; delete t2.* from t2,t5 where t2.a=t5.a + 1 master-bin.000001 # Query # # use `test`; ROLLBACK select count(*) from t1 /* must be 1 */; @@ -638,10 +893,13 @@ count(*) 2 show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Intvar # # INSERT_ID=10 -master-bin.000001 # Begin_load_query # # ;file_id=1;block_len=12 +master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci +master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=12 master-bin.000001 # Intvar # # INSERT_ID=10 -master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2) ;file_id=1 +master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci +master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2) ;file_id=# master-bin.000001 # Query # # use `test`; ROLLBACK drop trigger trg_del_t2; drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/suite/binlog/r/binlog_start_comment.result b/mysql-test/suite/binlog/r/binlog_start_comment.result new file mode 100644 index 00000000000..162968195f2 --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_start_comment.result @@ -0,0 +1,15 @@ +reset master; +drop table if exists t1,t2; +create table t1 (word varchar(20)) -- create table t1; +create table t2 (word varchar(20)) -- create table t2; +load data infile '../std_data_ln/words.dat' into table t1 -- load data to t1; +insert into t2 values ("Ada"); +flush logs; +select * from t2; +word +Ada +flush logs; +select * from t2; +word +Ada +drop table t1,t2; diff --git a/mysql-test/suite/binlog/r/binlog_stm_blackhole.result b/mysql-test/suite/binlog/r/binlog_stm_blackhole.result index a79642a9204..20e9bf6283e 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_blackhole.result +++ b/mysql-test/suite/binlog/r/binlog_stm_blackhole.result @@ -104,23 +104,40 @@ select * from t2; a select * from t3; a -show binlog events from <binlog_start>; +show binlog events; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Format_desc # # Server ver: VERSION, Binlog ver: 4 master-bin.000001 # Query # # use `test`; drop table t1,t2 master-bin.000001 # Query # # use `test`; create table t1 (a int) engine=blackhole +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; delete from t1 where a=10 +master-bin.000001 # Query # # use `test`; COMMIT +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; update t1 set a=11 where a=15 +master-bin.000001 # Query # # use `test`; COMMIT +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(1) +master-bin.000001 # Query # # use `test`; COMMIT +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; insert ignore into t1 values(1) +master-bin.000001 # Query # # use `test`; COMMIT +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; replace into t1 values(100) +master-bin.000001 # Query # # use `test`; COMMIT master-bin.000001 # Query # # use `test`; create table t2 (a varchar(200)) engine=blackhole -master-bin.000001 # Begin_load_query # # ;file_id=1;block_len=581 -master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/words.dat' into table t2 ;file_id=1 +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=581 +master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/words.dat' into table t2 ;file_id=# +master-bin.000001 # Query # # use `test`; COMMIT master-bin.000001 # Query # # use `test`; alter table t1 add b int master-bin.000001 # Query # # use `test`; alter table t1 drop b master-bin.000001 # Query # # use `test`; create table t3 like t1 +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; insert into t1 select * from t3 +master-bin.000001 # Query # # use `test`; COMMIT +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; replace into t1 select * from t3 +master-bin.000001 # Query # # use `test`; COMMIT drop table t1,t2,t3; CREATE TABLE t1(a INT) ENGINE=BLACKHOLE; INSERT DELAYED INTO t1 VALUES(1); @@ -147,8 +164,9 @@ start transaction; insert into t1 values(2); rollback; set autocommit=1; -show binlog events from <binlog_start>; +show binlog events; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Format_desc # # Server ver: VERSION, Binlog ver: 4 master-bin.000001 # Query # # use `test`; create table t1 (a int) engine=blackhole master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(1) diff --git a/mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result b/mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result index c789c618876..3030af7bd68 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result +++ b/mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result @@ -19,7 +19,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t2 values (@v)/*!*/; +insert into t2 values (@v) +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; diff --git a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result index c15478bc826..39927a8d866 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result @@ -100,6 +100,7 @@ insert into t1 values(9); insert into t2 select * from t1; show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(9) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; insert into t2 select * from t1 @@ -111,6 +112,7 @@ begin; insert into t2 select * from t1; show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(10) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; insert into t2 select * from t1 @@ -118,6 +120,7 @@ insert into t1 values(11); commit; show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(10) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; insert into t2 select * from t1 @@ -233,16 +236,20 @@ master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(16) master-bin.000001 # Query # # use `test`; insert into t1 values(18) master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; delete from t1 master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; delete from t2 master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; alter table t2 engine=MyISAM +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values (1) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; insert into t2 values (20) master-bin.000001 # Query # # use `test`; drop table t1,t2 master-bin.000001 # Query # # use `test`; create temporary table ti (a int) engine=innodb +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; insert into ti values(1) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; create temporary table t1 (a int) engine=myisam @@ -339,6 +346,7 @@ master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (3,3) master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t2 master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (a int, b int, primary key (a)) engine=innodb master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (4,4) +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; TRUNCATE table t2 master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (5,5) @@ -348,6 +356,7 @@ master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE t2 (a int, b in master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (7,7) master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (8,8) master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (9,9) +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; TRUNCATE table t2 master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (10,10) @@ -375,18 +384,260 @@ is not null; is not null 1 select -@a like "%#%error_code=0%ROLLBACK/*!*/;%ROLLBACK /* added by mysqlbinlog */;%", +@a like "%#%error_code=0%ROLLBACK\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" OR +@a like "%#%error_code=0%ROLLBACK\r\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%", @a not like "%#%error_code=%error_code=%"; -@a like "%#%error_code=0%ROLLBACK/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" @a not like "%#%error_code=%error_code=%" +@a like "%#%error_code=0%ROLLBACK\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" OR +@a like "%#%error_code=0%ROLLBACK\r\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" @a not like "%#%error_code=%error_code=%" 1 1 drop table t1, t2; +create temporary table tt (a int unique); +create table ti (a int) engine=innodb; +reset master; +begin; +insert into ti values (1); +insert into ti values (2) ; +insert into tt select * from ti; +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +select count(*) from tt /* 2 */; +count(*) +2 +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # use `test`; insert into ti values (1) +master-bin.000001 # Query # # use `test`; insert into ti values (2) +master-bin.000001 # Query # # use `test`; insert into tt select * from ti +master-bin.000001 # Query # # use `test`; ROLLBACK +select count(*) from ti /* zero */; +count(*) +0 +insert into ti select * from tt; +select * from ti /* that is what slave would miss - a bug */; +a +1 +2 +delete from ti; +delete from tt where a=1; +reset master; +begin; +insert into ti values (1); +insert into ti values (2) /* to make the dup error in the following */; +insert into tt select * from ti /* one affected and error */; +ERROR 23000: Duplicate entry '2' for key 'a' +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # use `test`; insert into ti values (1) +master-bin.000001 # Query # # use `test`; insert into ti values (2) /* to make the dup error in the following */ +master-bin.000001 # Query # # use `test`; insert into tt select * from ti /* one affected and error */ +master-bin.000001 # Query # # use `test`; ROLLBACK +select count(*) from ti /* zero */; +count(*) +0 +insert into ti select * from tt; +select * from tt /* that is what otherwise slave missed - the bug */; +a +1 +2 +drop table ti, tt; +drop function if exists bug27417; +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, PRIMARY KEY (a)); +create function bug27417(n int) +RETURNS int(11) +begin +insert into t1 values (null); +return n; +end| +reset master; +insert into t2 values (bug27417(1)); +insert into t2 select bug27417(2); +reset master; +insert into t2 values (bug27417(2)); +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Intvar # # INSERT_ID=3 +master-bin.000001 # Query # # use `test`; insert into t2 values (bug27417(2)) +/* only (!) with fixes for #23333 will show there is the query */; +select count(*) from t1 /* must be 3 */; +count(*) +3 +reset master; +select count(*) from t2; +count(*) +2 +delete from t2 where a=bug27417(3); +select count(*) from t2 /* nothing got deleted */; +count(*) +2 +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Intvar # # INSERT_ID=4 +master-bin.000001 # Query # # use `test`; delete from t2 where a=bug27417(3) +/* the query must be in regardless of #23333 */; +select count(*) from t1 /* must be 5 */; +count(*) +5 +delete t2 from t2 where t2.a=bug27417(100) /* must not affect t2 */; +affected rows: 0 +select count(*) from t1 /* must be 7 */; +count(*) +7 +drop table t1,t2; +CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM; +CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB; +CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique) ENGINE=MyISAM; +CREATE TABLE t4 (a int, PRIMARY KEY (a), b int unique) ENGINE=Innodb; +CREATE TABLE t5 (a int, PRIMARY KEY (a)) ENGINE=InnoDB; +insert into t2 values (1); +reset master; +insert into t2 values (bug27417(1)); +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Intvar # # INSERT_ID=1 +master-bin.000001 # Query # # use `test`; insert into t2 values (bug27417(1)) +master-bin.000001 # Query # # use `test`; ROLLBACK +/* the output must denote there is the query */; +select count(*) from t1 /* must be 1 */; +count(*) +1 +delete from t1; +delete from t2; +insert into t2 values (2); +reset master; +insert into t2 select bug27417(1) union select bug27417(2); +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Intvar # # INSERT_ID=2 +master-bin.000001 # Query # # use `test`; insert into t2 select bug27417(1) union select bug27417(2) +master-bin.000001 # Query # # use `test`; ROLLBACK +/* the output must denote there is the query */; +select count(*) from t1 /* must be 2 */; +count(*) +2 +delete from t1; +insert into t3 values (1,1),(2,3),(3,4); +reset master; +update t3 set b=b+bug27417(1); +ERROR 23000: Duplicate entry '4' for key 'b' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Intvar # # INSERT_ID=4 +master-bin.000001 # Query # # use `test`; update t3 set b=b+bug27417(1) +/* the output must denote there is the query */; +select count(*) from t1 /* must be 2 */; +count(*) +2 +delete from t3; +delete from t4; +insert into t3 values (1,1); +insert into t4 values (1,1),(2,2); +reset master; +UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */; +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Intvar # # INSERT_ID=6 +master-bin.000001 # Query # # use `test`; UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */ +master-bin.000001 # Query # # use `test`; ROLLBACK +/* the output must denote there is the query */; +select count(*) from t1 /* must be 4 */; +count(*) +4 +delete from t1; +delete from t3; +delete from t4; +insert into t3 values (1,1),(2,2); +insert into t4 values (1,1),(2,2); +reset master; +UPDATE t3,t4 SET t3.a=t4.a + bug27417(1); +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +select count(*) from t1 /* must be 1 */; +count(*) +1 +drop table t4; +delete from t1; +delete from t2; +delete from t3; +insert into t2 values (1); +insert into t3 values (1,1); +create trigger trg_del before delete on t2 for each row +insert into t3 values (bug27417(1), 2); +reset master; +delete from t2; +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Intvar # # INSERT_ID=9 +master-bin.000001 # Query # # use `test`; delete from t2 +master-bin.000001 # Query # # use `test`; ROLLBACK +/* the output must denote there is the query */; +select count(*) from t1 /* must be 1 */; +count(*) +1 +drop trigger trg_del; +delete from t1; +delete from t2; +delete from t5; +create trigger trg_del_t2 after delete on t2 for each row +insert into t1 values (1); +insert into t2 values (2),(3); +insert into t5 values (1),(2); +reset master; +delete t2.* from t2,t5 where t2.a=t5.a + 1; +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # use `test`; delete t2.* from t2,t5 where t2.a=t5.a + 1 +master-bin.000001 # Query # # use `test`; ROLLBACK +/* the output must denote there is the query */; +select count(*) from t1 /* must be 1 */; +count(*) +1 +delete from t1; +create table t4 (a int default 0, b int primary key) engine=innodb; +insert into t4 values (0, 17); +reset master; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2); +ERROR 23000: Duplicate entry '17' for key 'PRIMARY' +select * from t4; +a b +0 17 +select count(*) from t1 /* must be 2 */; +count(*) +2 +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Intvar # # INSERT_ID=10 +master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=12 +master-bin.000001 # Intvar # # INSERT_ID=10 +master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2) ;file_id=# +master-bin.000001 # Query # # use `test`; ROLLBACK +/* the output must denote there is the query */; +drop trigger trg_del_t2; +drop table t1,t2,t3,t4,t5; +drop function bug27417; +end of tests set @@session.binlog_format=statement; create temporary table tt (a int unique); create table ti (a int) engine=innodb; reset master; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 106 begin; insert into ti values (1); insert into ti values (2) ; @@ -397,9 +648,6 @@ Warning 1196 Some non-transactional changed tables couldn't be rolled back select count(*) from tt /* 2 */; count(*) 2 -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 515 show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; BEGIN @@ -418,9 +666,6 @@ a delete from ti; delete from tt where a=1; reset master; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 106 begin; insert into ti values (1); insert into ti values (2) /* to make the dup error in the following */; @@ -429,9 +674,6 @@ ERROR 23000: Duplicate entry '2' for key 'a' rollback; Warnings: Warning 1196 Some non-transactional changed tables couldn't be rolled back -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 589 show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; BEGIN @@ -503,6 +745,7 @@ insert into t2 values (bug27417(1)); ERROR 23000: Duplicate entry '1' for key 'PRIMARY' show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Intvar # # INSERT_ID=1 master-bin.000001 # Query # # use `test`; insert into t2 values (bug27417(1)) master-bin.000001 # Query # # use `test`; ROLLBACK @@ -517,6 +760,7 @@ insert into t2 select bug27417(1) union select bug27417(2); ERROR 23000: Duplicate entry '2' for key 'PRIMARY' show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Intvar # # INSERT_ID=2 master-bin.000001 # Query # # use `test`; insert into t2 select bug27417(1) union select bug27417(2) master-bin.000001 # Query # # use `test`; ROLLBACK @@ -544,6 +788,7 @@ UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */; ERROR 23000: Duplicate entry '2' for key 'PRIMARY' show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Intvar # # INSERT_ID=6 master-bin.000001 # Query # # use `test`; UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */ master-bin.000001 # Query # # use `test`; ROLLBACK @@ -574,6 +819,7 @@ delete from t2; ERROR 23000: Duplicate entry '1' for key 'PRIMARY' show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Intvar # # INSERT_ID=9 master-bin.000001 # Query # # use `test`; delete from t2 master-bin.000001 # Query # # use `test`; ROLLBACK @@ -593,6 +839,7 @@ delete t2.* from t2,t5 where t2.a=t5.a + 1; ERROR 23000: Duplicate entry '1' for key 'PRIMARY' show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; delete t2.* from t2,t5 where t2.a=t5.a + 1 master-bin.000001 # Query # # use `test`; ROLLBACK select count(*) from t1 /* must be 1 */; @@ -612,10 +859,13 @@ count(*) 2 show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Intvar # # INSERT_ID=10 -master-bin.000001 # Begin_load_query # # ;file_id=1;block_len=12 +master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci +master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=12 master-bin.000001 # Intvar # # INSERT_ID=10 -master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2) ;file_id=1 +master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci +master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2) ;file_id=# master-bin.000001 # Query # # use `test`; ROLLBACK drop trigger trg_del_t2; drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/r/binlog_unsafe.result b/mysql-test/suite/binlog/r/binlog_unsafe.result index 8467a18aa6b..8467a18aa6b 100644 --- a/mysql-test/r/binlog_unsafe.result +++ b/mysql-test/suite/binlog/r/binlog_unsafe.result diff --git a/mysql-test/suite/binlog/std_data/binlog-bug32407.000001 b/mysql-test/suite/binlog/std_data/binlog-bug32407.000001 Binary files differnew file mode 100644 index 00000000000..c73243707ef --- /dev/null +++ b/mysql-test/suite/binlog/std_data/binlog-bug32407.000001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-telco.000001 b/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-telco.000001 Binary files differnew file mode 100644 index 00000000000..76856cb04a2 --- /dev/null +++ b/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-telco.000001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_row.000001 b/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_row.000001 Binary files differnew file mode 100644 index 00000000000..47071c011f9 --- /dev/null +++ b/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_row.000001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_stm.000001 b/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_stm.000001 Binary files differnew file mode 100644 index 00000000000..4302bfed879 --- /dev/null +++ b/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_stm.000001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1_17.000001 b/mysql-test/suite/binlog/std_data/binlog_old_version_5_1_17.000001 Binary files differnew file mode 100644 index 00000000000..9b6e200e492 --- /dev/null +++ b/mysql-test/suite/binlog/std_data/binlog_old_version_5_1_17.000001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1_23.000001 b/mysql-test/suite/binlog/std_data/binlog_old_version_5_1_23.000001 Binary files differnew file mode 100644 index 00000000000..0e9a9d1470a --- /dev/null +++ b/mysql-test/suite/binlog/std_data/binlog_old_version_5_1_23.000001 diff --git a/mysql-test/suite/binlog/t/binlog_base64_flag.test b/mysql-test/suite/binlog/t/binlog_base64_flag.test new file mode 100644 index 00000000000..32319460ab8 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_base64_flag.test @@ -0,0 +1,102 @@ +# This test case verifies that the mysqlbinlog --base64-output=X flags +# work as expected, and that BINLOG statements with row events fail if +# they are not preceded by BINLOG statements with Format description +# events. +# +# See also BUG#32407. + + +# Test to show BUG#32407. This reads a binlog created with the +# mysql-5.1-telco-6.1 tree, specifically at the tag +# mysql-5.1.15-ndb-6.1.23, and applies it to the database. The test +# should fail before BUG#32407 was fixed and succeed afterwards. +--echo ==== Test BUG#32407 ==== + +# The binlog contains row events equivalent to: +# CREATE TABLE t1 (a int) engine = myisam +# INSERT INTO t1 VALUES (1), (1) +exec $MYSQL_BINLOG suite/binlog/std_data/binlog-bug32407.000001 | $MYSQL; +# The above line should succeed and t1 should contain two ones +select * from t1; + + +# Test that a BINLOG statement encoding a row event fails unless a +# Format_description_event as been supplied with an earlier BINLOG +# statement. +--echo ==== Test BINLOG statement w/o FD event ==== + +# This is a binlog statement consisting of one Table_map_log_event and +# one Write_rows_log_event. Together, they correspond to the +# following query: +# INSERT INTO TABLE test.t1 VALUES (2) + +error ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT; +BINLOG ' +SVtYRxMBAAAAKQAAADQBAAAAABAAAAAAAAAABHRlc3QAAnQxAAEDAAE= +SVtYRxcBAAAAIgAAAFYBAAAQABAAAAAAAAEAAf/+AgAAAA== +'; +# The above line should fail and 2 should not be in the table +select * from t1; + + +# Test that it works to read a Format_description_log_event with a +# BINLOG statement, followed by a row-event in base64 from the same +# version. +--echo ==== Test BINLOG statement with FD event ==== + +# This is a binlog statement containing a Format_description_log_event +# from the same version as the Table_map and Write_rows_log_event. +BINLOG ' +ODdYRw8BAAAAZgAAAGoAAAABAAQANS4xLjIzLXJjLWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAA4N1hHEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC +'; + +# This is a Table_map_log_event+Write_rows_log_event corresponding to: +# INSERT INTO TABLE test.t1 VALUES (3) +BINLOG ' +TFtYRxMBAAAAKQAAAH8BAAAAABAAAAAAAAAABHRlc3QAAnQxAAEDAAE= +TFtYRxcBAAAAIgAAAKEBAAAQABAAAAAAAAEAAf/+AwAAAA== +'; +# The above line should succeed and 3 should be in the table +select * from t1; + + +# Test that mysqlbinlog stops with an error message when the +# --base64-output=never flag is used on a binlog with base64 events. +--echo ==== Test --base64-output=never on a binlog with row events ==== + +# mysqlbinlog should fail +--replace_regex /#[0-9][0-9][0-9][0-9][0-9][0-9] .*/#/ +error 1; +exec $MYSQL_BINLOG --base64-output=never suite/binlog/std_data/binlog-bug32407.000001; +# the above line should output the query log event and then stop + + +# Test that the following fails cleanly: "First, read a +# Format_description event which has N event types. Then, read an +# event of type M>N" +--echo ==== Test non-matching FD event and Row event ==== + +# This is the Format_description_log_event from +# binlog-bug32407.000001, encoded in base64. It contains only the old +# row events (number of event types is 22) +BINLOG ' +4CdYRw8BAAAAYgAAAGYAAAAAAAQANS4xLjE1LW5kYi02LjEuMjQtZGVidWctbG9nAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAADgJ1hHEzgNAAgAEgAEBAQEEgAATwAEGggICAg= +'; + +# The following is a Write_rows_log_event with event type 23, i.e., +# not supported by the Format_description_log_event above. It +# corresponds to the following query: +# INSERT INTO t1 VALUES (5) +error 1149; +BINLOG ' +Dl1YRxMBAAAAKQAAADQBAAAAABAAAAAAAAAABHRlc3QAAnQxAAEDAAE= +Dl1YRxcBAAAAIgAAAFYBAAAQABAAAAAAAAEAAf/+BQAAAA== +'; +# the above line should fail and 5 should not be in the binlog. +select * from t1; + + +# clean up +drop table t1; diff --git a/mysql-test/suite/binlog/t/binlog_old_versions.test b/mysql-test/suite/binlog/t/binlog_old_versions.test new file mode 100644 index 00000000000..2d56ebd588d --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_old_versions.test @@ -0,0 +1,148 @@ +# Test that old binlog formats can be read. + +# Some previous versions of MySQL use their own binlog format, +# especially in row-based replication. This test uses saved binlogs +# from those old versions to test that we can replicate from old +# versions to the present version. + +# Replicating from old versions to new versions is necessary in an +# online upgrade scenario, where the . + +# The previous versions we currently test are: +# - version 5.1.17 and earlier trees +# - mysql-5.1-wl2325-xxx trees (AKA alcatel trees) +# - mysql-5.1-telco-6.1 trees (AKA ndb trees) +# For completeness, we also test mysql-5.1-new_rpl, which is supposed +# to be the "correct" version. + +# All binlogs were generated with the same commands (listed at the end +# of this test for reference). The binlogs contain the following +# events: Table_map, Write_rows, Update_rows, Delete_rows Query, Xid, +# User_var, Int_var, Rand, Begin_load, Append_file, Execute_load. + +# Related bugs: BUG#27779, BUG#31581, BUG#31582, BUG#31583, BUG#32407 + +source include/not_embedded.inc; + +--disable_warnings +DROP TABLE IF EXISTS t1, t2, t3; + + +--echo ==== Read modern binlog (version 5.1.23) ==== + +# Read binlog. +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1_23.000001 | $MYSQL --local-infile=1 +# Show result. +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT COUNT(*) FROM t3; +# Reset. +DROP TABLE t1, t2, t3; + + +--echo ==== Read binlog from version 5.1.17 ==== + +# Read binlog. +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1_17.000001 | $MYSQL --local-infile=1 +# Show result. +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT COUNT(*) FROM t3; +# Reset. +DROP TABLE t1, t2, t3; + + +--echo ==== Read binlog from alcatel tree (mysql-5.1-wl2325-5.0-drop6) ==== + +# In this version, it was not possible to switch between row-based and +# statement-based binlogging without restarting the server. So, we +# have two binlogs; one for row based and one for statement based +# replication. + +# Read rbr binlog. +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1-wl2325_row.000001 | $MYSQL --local-infile=1 +# Read stm binlog. +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1-wl2325_stm.000001 | $MYSQL --local-infile=1 +# Show result. +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT COUNT(*) FROM t3; +# Reset. +DROP TABLE t1, t2, t3; + + +--echo ==== Read binlog from ndb tree (mysql-5.1-telco-6.1) ==== + +# Read binlog. +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1-telco.000001 | $MYSQL --local-infile=1 +# Show resulting tablea. +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT COUNT(*) FROM t3; +# Reset. +DROP TABLE t1, t2, t3; + + +#### The following commands were used to generate the binlogs #### +# +#source include/master-slave.inc; +# +## ==== initialize ==== +#USE test; +#CREATE TABLE t1 (a int, b char(50)) ENGINE = MyISAM; +#CREATE TABLE t2 (a int, b char(50)) ENGINE = InnoDB; +#CREATE TABLE t3 (a char(20)); +# +# +## ==== row based tests ==== +#SET BINLOG_FORMAT='row'; +# +## ---- get write, update, and delete rows events ---- +#INSERT INTO t1 VALUES (0, 'one'), (1, 'two'); +#UPDATE t1 SET a=a+1; +#DELETE FROM t1 WHERE a=2; +# +# +## ==== statement based tests ==== +#SET BINLOG_FORMAT = 'statement'; +# +## ---- get xid events ---- +#BEGIN; +#INSERT INTO t2 VALUES (3, 'first stm in trx'); +#INSERT INTO t1 VALUES (3, 'last stm in trx: next event should be xid'); +#COMMIT; +# +## ---- get user var events ---- +#SET @x = 4; +#INSERT INTO t1 VALUES (@x, 'four'); +# +## ---- get rand event ---- +#INSERT INTO t1 VALUES (RAND() * 1000000, 'random'); +# +## ---- get intvar event ---- +#INSERT INTO t1 VALUES (LAST_INSERT_ID(), 'last_insert_id'); +# +## ---- get begin, append and execute load events ---- +## double the file until we have more than 2^17 bytes, so that the +## event has to be split and we can use Append_file_log_event. +# +#SET SQL_LOG_BIN=0; +#CREATE TABLE temp (a char(20)); +#LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE temp; +#INSERT INTO temp SELECT * FROM temp; +#INSERT INTO temp SELECT * FROM temp; +#INSERT INTO temp SELECT * FROM temp; +#INSERT INTO temp SELECT * FROM temp; +#INSERT INTO temp SELECT * FROM temp; +#INSERT INTO temp SELECT * FROM temp; +#INSERT INTO temp SELECT * FROM temp; +#INSERT INTO temp SELECT * FROM temp; +#SELECT a FROM temp INTO OUTFILE 'big_file.dat'; +#DROP TABLE temp; +#SET SQL_LOG_BIN=1; +# +#LOAD DATA INFILE 'big_file.dat' INTO TABLE t3; +# +#SELECT * FROM t1 ORDER BY a; +#SELECT * FROM t2 ORDER BY a; +#SELECT COUNT(*) FROM t3; diff --git a/mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam.test b/mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam.test index 3148cc50fd0..a7722075d6e 100644 --- a/mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam.test +++ b/mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam.test @@ -12,24 +12,4 @@ --enable_ps_protocol -# This piece below cannot be put into -# extra/binlog_tests/mix_innodb_myisam_binlog.test -# because the argument of --start-position differs between statement- -# and row-based (and "eval --exec" doesn't work). -# we check that the error code of the "ROLLBACK" event is 0 and not -# ER_SERVER_SHUTDOWN (i.e. disconnection just rolls back transaction -# and does not make slave to stop) -flush logs; ---exec $MYSQL_BINLOG --start-position=524 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR -eval select -(@a:=load_file("$MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output")) -is not null; - ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR -eval select -@a like "%#%error_code=0%ROLLBACK/*!*/;%ROLLBACK /* added by mysqlbinlog */;%", -@a not like "%#%error_code=%error_code=%"; -drop table t1, t2; - -- source extra/binlog_tests/mix_innodb_myisam_side_effects.test diff --git a/mysql-test/suite/binlog/t/binlog_start_comment.test b/mysql-test/suite/binlog/t/binlog_start_comment.test new file mode 100644 index 00000000000..a5817eb69b7 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_start_comment.test @@ -0,0 +1,24 @@ +# Test case for bug#32205 Replaying statements from mysqlbinlog fails +# with a syntax error, replicates fine + +source include/have_log_bin.inc; +source include/have_local_infile.inc; + +reset master; +--disable_warnings +drop table if exists t1,t2; +--enable_warnings +create table t1 (word varchar(20)) -- create table t1; +create table t2 (word varchar(20)) -- create table t2; +load data infile '../std_data_ln/words.dat' into table t1 -- load data to t1; +insert into t2 values ("Ada"); +flush logs; +select * from t2; +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_start_comment.binlog +--exec $MYSQL --local-infile=1 < $MYSQLTEST_VARDIR/tmp/binlog_start_comment.binlog +flush logs; +select * from t2; + +# clean up +drop table t1,t2; +#--system rm $MYSQLTEST_VARDIR/tmp/binlog_start_comment.binlog diff --git a/mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test b/mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test index e7149e03b87..e4661526982 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test +++ b/mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test @@ -1,29 +1,9 @@ # This is a wrapper for binlog.test so that the same test case can be used # For both statement and row based bin logs 9/19/2005 [jbm] --- source include/have_binlog_format_mixed_or_statement.inc +-- source include/have_binlog_format_statement.inc -- source extra/binlog_tests/mix_innodb_myisam_binlog.test -# This piece below cannot be put into -# extra/binlog_tests/mix_innodb_myisam_binlog.test -# because the argument of --start-position differs between statement- -# and row-based (and "eval --exec" doesn't work). -# we check that the error code of the "ROLLBACK" event is 0 and not -# ER_SERVER_SHUTDOWN (i.e. disconnection just rolls back transaction -# and does not make slave to stop) -flush logs; ---exec $MYSQL_BINLOG --start-position=555 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR -eval select -(@a:=load_file("$MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output")) -is not null; ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR -eval select -@a like "%#%error_code=0%ROLLBACK/*!*/;%ROLLBACK /* added by mysqlbinlog */;%", -@a not like "%#%error_code=%error_code=%"; - -drop table t1, t2; - set @@session.binlog_format=statement; -- source extra/binlog_tests/mix_innodb_myisam_side_effects.test set @@session.binlog_format=@@global.binlog_format; diff --git a/mysql-test/t/binlog_unsafe.test b/mysql-test/suite/binlog/t/binlog_unsafe.test index 209e16e0cc0..209e16e0cc0 100644 --- a/mysql-test/t/binlog_unsafe.test +++ b/mysql-test/suite/binlog/t/binlog_unsafe.test diff --git a/mysql-test/suite/binlog/t/disabled.def b/mysql-test/suite/binlog/t/disabled.def index a6e73fa31d8..c93bc2a158e 100644 --- a/mysql-test/suite/binlog/t/disabled.def +++ b/mysql-test/suite/binlog/t/disabled.def @@ -10,3 +10,4 @@ # ############################################################################## binlog_multi_engine : Bug#32663 binlog_multi_engine.test fails randomly +binlog_base64_flag : BUG#33247 2007-12-14 Sven: mysqlbinlog does not clean up after itself on termination. When compiled in debug mode, this test generates lots of warnings for memory leaks. diff --git a/mysql-test/suite/bugs/r/rpl_bug31582.result b/mysql-test/suite/bugs/r/rpl_bug31582.result new file mode 100644 index 00000000000..1f71fbf8fe7 --- /dev/null +++ b/mysql-test/suite/bugs/r/rpl_bug31582.result @@ -0,0 +1,16 @@ +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; +CREATE TABLE t1 (a VARCHAR(10) PRIMARY KEY) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('a'); +UPDATE t1 SET a = 'MyISAM'; +SELECT * FROM t1 ORDER BY a; +a +MyISAM +SELECT * FROM t1 ORDER BY a; +a +MyISAM +DROP TABLE t1; diff --git a/mysql-test/suite/bugs/r/rpl_bug31583.result b/mysql-test/suite/bugs/r/rpl_bug31583.result new file mode 100644 index 00000000000..a5e38e9b2d8 --- /dev/null +++ b/mysql-test/suite/bugs/r/rpl_bug31583.result @@ -0,0 +1,15 @@ +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; +CREATE TABLE t1 ( a INT, b INT DEFAULT -3 ); +INSERT INTO t1 VALUES (1, DEFAULT); +UPDATE t1 SET a = 3; +SELECT * FROM t1 ORDER BY a; +a b +3 -3 +SELECT * FROM t1 ORDER BY a; +a b +3 -3 diff --git a/mysql-test/suite/bugs/t/rpl_bug31582.test b/mysql-test/suite/bugs/t/rpl_bug31582.test new file mode 100644 index 00000000000..7ba15eec8ce --- /dev/null +++ b/mysql-test/suite/bugs/t/rpl_bug31582.test @@ -0,0 +1,25 @@ + +# BUG#31582: 5.1-telco-6.1 -> 5.1.22. Slave crashes when reading +# UPDATE for VARCHAR + +# This is a problem for any update statement replicating from an old +# server to a new server. The bug consisted of a new slave trying to +# read two column bitmaps, but there is only one available in the old +# format. + +# This test case should be executed replicating from an old server to +# a new server, so make sure you have one handy. + +source include/master-slave.inc; + +CREATE TABLE t1 (a VARCHAR(10) PRIMARY KEY) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('a'); +UPDATE t1 SET a = 'MyISAM'; +SELECT * FROM t1 ORDER BY a; +sync_slave_with_master; +SELECT * FROM t1 ORDER BY a; + +connection master; +DROP TABLE t1; +sync_slave_with_master; + diff --git a/mysql-test/suite/bugs/t/rpl_bug31583.test b/mysql-test/suite/bugs/t/rpl_bug31583.test new file mode 100644 index 00000000000..657e4984b77 --- /dev/null +++ b/mysql-test/suite/bugs/t/rpl_bug31583.test @@ -0,0 +1,25 @@ +# +# BUG#31583: 5.1-telco-6.1 -> 5.1.22. Slave returns Error in unknown event + +# This is a problem for any update statement replicating from an old +# server to a new server. The bug consisted of a new slave trying to +# read two column bitmaps, but there is only one available in the old +# format. + +# This test case should be executed replicating from an old server to +# a new server, so make sure you have one handy. + +source include/master-slave.inc; + +CREATE TABLE t1 ( a INT, b INT DEFAULT -3 ); + +INSERT INTO t1 VALUES (1, DEFAULT); +UPDATE t1 SET a = 3; +SELECT * FROM t1 ORDER BY a; +sync_slave_with_master; +SELECT * FROM t1 ORDER BY a; + +connection master; +DROP TABLE t1; +sync_slave_with_master; + diff --git a/mysql-test/suite/ndb/r/ndb_binlog_format.result b/mysql-test/suite/ndb/r/ndb_binlog_format.result index ed26060e2a4..b42a528a460 100644 --- a/mysql-test/suite/ndb/r/ndb_binlog_format.result +++ b/mysql-test/suite/ndb/r/ndb_binlog_format.result @@ -15,8 +15,12 @@ COMMIT; show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (1,2), (2,1), (2,2) +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; INSERT INTO t2 VALUES (1,1), (1,2), (2,1), (2,2) +master-bin.000001 # Query # # use `test`; COMMIT +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; UPDATE t1, t2 SET m = 2, b = 3 WHERE n = c +master-bin.000001 # Query # # use `test`; COMMIT master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (1,1), (1,2), (2,1), (2,2) master-bin.000001 # Query # # use `test`; UPDATE t1, t3 SET m = 2, e = 3 WHERE n = f diff --git a/mysql-test/suite/ndb/r/ps_7ndb.result b/mysql-test/suite/ndb/r/ps_7ndb.result index 70d511d5398..b53a3cf3393 100644 --- a/mysql-test/suite/ndb/r/ps_7ndb.result +++ b/mysql-test/suite/ndb/r/ps_7ndb.result @@ -1286,12 +1286,11 @@ a b set @arg00=NULL; set @arg01=2; execute stmt1 using @arg00, @arg01; -Warnings: -Warning 1048 Column 'a' cannot be null +ERROR 23000: Column 'a' cannot be null select a,b from t1 order by a; a b -0 two 1 one +2 two 3 three 4 four set @arg00=0; diff --git a/mysql-test/suite/parts/t/disabled.def b/mysql-test/suite/parts/t/disabled.def index 85b31bb0598..97dce441cc2 100644 --- a/mysql-test/suite/parts/t/disabled.def +++ b/mysql-test/suite/parts/t/disabled.def @@ -3,16 +3,23 @@ ndb_dd_backuprestore : cannot create t1 ndb_partition_error : cannot create t1 ndb_partition_list : cannot create t1 ndb_partition_range : cannot create t1 +part_supported_sql_func_ndb : cannot create t1 +partition_alter1_ndb : timeout. Needs too much time. +partition_alter2_ndb : cannot create t1 +partition_basic_ndb : cannot create t1 +partition_bit_myisam : BUG#34225 2008-02-02 mats test suit parts uses /tmp-dir instead of mysql-test dir, which causes failures partition_bit_ndb : cannot create t1 +partition_char_myisam : BUG#34225 2008-02-02 mats test suit parts uses /tmp-dir instead of mysql-test dir, which causes failures +partition_datetime_myisam : BUG#34225 2008-02-02 mats test suit parts uses /tmp-dir instead of mysql-test dir, which causes failures +partition_decimal_myisam : BUG#34225 2008-02-02 mats test suit parts uses /tmp-dir instead of mysql-test dir, which causes failures +partition_engine_ndb : cannot create t1 +partition_float_myisam : BUG#34225 2008-02-02 mats test suit parts uses /tmp-dir instead of mysql-test dir, which causes failures +partition_int_myisam : BUG#34225 2008-02-02 mats test suit parts uses /tmp-dir instead of mysql-test dir, which causes failures partition_int_ndb : cannot create t1 +partition_sessions : needs system_3_init.inc +partition_special_myisam : BUG#34225 2008-02-02 mats test suit parts uses /tmp-dir instead of mysql-test dir, which causes failures partition_syntax_ndb : cannot create t1 -partition_value_myisam : Bug#30581 partition_value tests use disallowed CAST() function partition_value_innodb : Bug#30581 partition_value tests use disallowed CAST() function +partition_value_myisam : Bug#30581 partition_value tests use disallowed CAST() function partition_value_ndb : cannot create t1 -partition_basic_ndb : cannot create t1 -partition_alter1_ndb : timeout. Needs too much time. -partition_alter2_ndb : cannot create t1 -partition_sessions : needs system_3_init.inc -partition_engine_ndb : cannot create t1 -part_supported_sql_func_ndb : cannot create t1 rpl_ndb_dd_partitions : cannot create t1 diff --git a/mysql-test/suite/rpl/combinations b/mysql-test/suite/rpl/combinations new file mode 100644 index 00000000000..ea25611a5d4 --- /dev/null +++ b/mysql-test/suite/rpl/combinations @@ -0,0 +1,8 @@ +[row] +--binlog-format=row + +[stmt] +--binlog-format=statement + +[mix] +--binlog-format=mixed diff --git a/mysql-test/suite/rpl/r/rpl_000015.result b/mysql-test/suite/rpl/r/rpl_000015.result index 79d87354cb2..03b96d5870b 100644 --- a/mysql-test/suite/rpl/r/rpl_000015.result +++ b/mysql-test/suite/rpl/r/rpl_000015.result @@ -1,7 +1,7 @@ reset master; show master status; File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 106 +master-bin.000001 # <Binlog_Do_DB> <Binlog_Ignore_DB> reset slave; SHOW SLAVE STATUS; change master to master_host='127.0.0.1'; @@ -12,7 +12,7 @@ Master_User test Master_Port 3306 Connect_Retry 7 Master_Log_File -Read_Master_Log_Pos 4 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File @@ -27,7 +27,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 0 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -53,7 +53,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 7 Master_Log_File -Read_Master_Log_Pos 4 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File @@ -68,7 +68,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 0 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -93,7 +93,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 7 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 106 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -108,7 +108,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 106 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/suite/rpl/r/rpl_bug31076.result b/mysql-test/suite/rpl/r/rpl_bug31076.result index fb819b03ad3..fd66ca85d57 100644 --- a/mysql-test/suite/rpl/r/rpl_bug31076.result +++ b/mysql-test/suite/rpl/r/rpl_bug31076.result @@ -40,6 +40,10 @@ KEY `data` (`data`) /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; BINLOG ' +O1ZVRw8BAAAAZgAAAGoAAAAAAAQANS4xLjIzLXJjLWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAA7VlVHEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC +'/*!*/; +BINLOG ' Bk3vRhO0AQAAOAAAALcLyQkAAJlXFwIAAAAABXRyYWNrAA12aXNpdHNfZXZlbnRzAAYJAwcPDwM= Bk3vRhe0AQAAWgAAABEMyQkQAJlXFwIAAAEABv/AIE4AvvVDAQZN70YAK0Rvd25sb2Fkcy9NeVNR TC00LjEvbXlzcWwtNC4xLjEyYS13aW4zMi56aXBPaAIC diff --git a/mysql-test/suite/rpl/r/rpl_change_master.result b/mysql-test/suite/rpl/r/rpl_change_master.result index 7707ca2cf9b..c06c1201e3d 100644 --- a/mysql-test/suite/rpl/r/rpl_change_master.result +++ b/mysql-test/suite/rpl/r/rpl_change_master.result @@ -33,7 +33,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 191 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -73,7 +73,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 191 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/suite/rpl/r/rpl_create_database.result b/mysql-test/suite/rpl/r/rpl_create_database.result index 0cfd44bc58c..9780b65f334 100644 --- a/mysql-test/suite/rpl/r/rpl_create_database.result +++ b/mysql-test/suite/rpl/r/rpl_create_database.result @@ -20,21 +20,17 @@ INSERT INTO t2 VALUES(2); ALTER DATABASE mysqltest_sisyfos CHARACTER SET latin1; USE mysqltest_sisyfos; ALTER DATABASE mysqltest_bob CHARACTER SET latin1; -SHOW DATABASES; -Database -information_schema +SHOW DATABASES LIKE 'mysql%'; +Database (mysql%) mysql mysqltest_bob mysqltest_prometheus mysqltest_sisyfos -test -SHOW DATABASES; -Database -information_schema +SHOW DATABASES LIKE 'mysql%'; +Database (mysql%) mysql mysqltest_prometheus mysqltest_sisyfos -test DROP DATABASE IF EXISTS mysqltest_sisyfos; USE mysqltest_prometheus; CREATE TABLE t1 (a INT); @@ -42,21 +38,17 @@ INSERT INTO t1 VALUES (1); CREATE DATABASE mysqltest_sisyfos; USE mysqltest_sisyfos; CREATE TABLE t2 (a INT); -SHOW DATABASES; -Database -information_schema +SHOW DATABASES LIKE 'mysql%'; +Database (mysql%) mysql mysqltest_bob mysqltest_prometheus mysqltest_sisyfos -test -SHOW DATABASES; -Database -information_schema +SHOW DATABASES LIKE 'mysql%'; +Database (mysql%) mysql mysqltest_prometheus mysqltest_sisyfos -test USE mysqltest_prometheus; SHOW TABLES; Tables_in_mysqltest_prometheus diff --git a/mysql-test/suite/rpl/r/rpl_drop_view.result b/mysql-test/suite/rpl/r/rpl_drop_view.result new file mode 100644 index 00000000000..ef625464881 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_drop_view.result @@ -0,0 +1,27 @@ +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 table if exists t1, t2; +drop view if exists v1, v2, v3, not_exist_view; +create table t1 (a int); +create table t2 (b int); +create table t3 (c int); +create view v1 as select * from t1; +create view v2 as select * from t2; +create view v3 as select * from t3; +drop view not_exist_view; +ERROR 42S02: Unknown table 'not_exist_view' +drop view v1, not_exist_view; +ERROR 42S02: Unknown table 'not_exist_view' +select * from v1; +ERROR 42S02: Table 'test.v1' doesn't exist +drop view v2, v3; +select * from v1; +ERROR 42S02: Table 'test.v1' doesn't exist +select * from v2; +ERROR 42S02: Table 'test.v2' doesn't exist +select * from v3; +ERROR 42S02: Table 'test.v3' doesn't exist diff --git a/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result b/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result index ad67f96db71..86648ba12c3 100644 --- a/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result @@ -454,9 +454,7 @@ f1 f2 f3 f4 update t31 set f5=555555555555555 where f3=6; update t31 set f2=2 where f3=2; update t31 set f1=NULL where f3=1; -update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; -Warnings: -Warning 1048 Column 'f3' cannot be null +update t31 set f3=0, f27=NULL, f35='f35 new value' where f3=3; ** Delete from Master ** @@ -1595,9 +1593,7 @@ f1 f2 f3 f4 update t31 set f5=555555555555555 where f3=6; update t31 set f2=2 where f3=2; update t31 set f1=NULL where f3=1; -update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; -Warnings: -Warning 1048 Column 'f3' cannot be null +update t31 set f3=0, f27=NULL, f35='f35 new value' where f3=3; ** Delete from Master ** @@ -2736,9 +2732,7 @@ f1 f2 f3 f4 update t31 set f5=555555555555555 where f3=6; update t31 set f2=2 where f3=2; update t31 set f1=NULL where f3=1; -update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; -Warnings: -Warning 1048 Column 'f3' cannot be null +update t31 set f3=0, f27=NULL, f35='f35 new value' where f3=3; ** Delete from Master ** diff --git a/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result b/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result index 8859a8e24e3..96d4ca237d1 100644 --- a/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result +++ b/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result @@ -454,9 +454,7 @@ f1 f2 f3 f4 update t31 set f5=555555555555555 where f3=6; update t31 set f2=2 where f3=2; update t31 set f1=NULL where f3=1; -update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; -Warnings: -Warning 1048 Column 'f3' cannot be null +update t31 set f3=0, f27=NULL, f35='f35 new value' where f3=3; ** Delete from Master ** @@ -1595,9 +1593,7 @@ f1 f2 f3 f4 update t31 set f5=555555555555555 where f3=6; update t31 set f2=2 where f3=2; update t31 set f1=NULL where f3=1; -update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; -Warnings: -Warning 1048 Column 'f3' cannot be null +update t31 set f3=0, f27=NULL, f35='f35 new value' where f3=3; ** Delete from Master ** @@ -2736,9 +2732,7 @@ f1 f2 f3 f4 update t31 set f5=555555555555555 where f3=6; update t31 set f2=2 where f3=2; update t31 set f1=NULL where f3=1; -update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; -Warnings: -Warning 1048 Column 'f3' cannot be null +update t31 set f3=0, f27=NULL, f35='f35 new value' where f3=3; ** Delete from Master ** diff --git a/mysql-test/suite/rpl/r/rpl_foreign_key_innodb.result b/mysql-test/suite/rpl/r/rpl_foreign_key_innodb.result index 2239c32eea3..e7a912b75fa 100644 --- a/mysql-test/suite/rpl/r/rpl_foreign_key_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_foreign_key_innodb.result @@ -40,3 +40,16 @@ Got one of the listed errors SET FOREIGN_KEY_CHECKS=0; DROP TABLE IF EXISTS t1,t2,t3; SET FOREIGN_KEY_CHECKS=1; +create table t1 (b int primary key) engine = INNODB; +create table t2 (a int primary key, b int, foreign key (b) references t1(b)) +engine = INNODB; +insert into t1 set b=1; +insert into t2 set a=1, b=1; +set foreign_key_checks=0; +set @@session.binlog_format=row; +delete from t1; +must sync w/o a problem (could not with the buggy code) +select count(*) from t1 /* must be zero */; +count(*) +0 +drop table t2,t1; diff --git a/mysql-test/suite/rpl/r/rpl_grant.result b/mysql-test/suite/rpl/r/rpl_grant.result index 935d1ca67c7..1bed6101e3c 100644 --- a/mysql-test/suite/rpl/r/rpl_grant.result +++ b/mysql-test/suite/rpl/r/rpl_grant.result @@ -7,40 +7,40 @@ start slave; **** On Master **** CREATE USER dummy@localhost; CREATE USER dummy1@localhost, dummy2@localhost; -SELECT user, host FROM mysql.user WHERE user != 'root'; +SELECT user, host FROM mysql.user WHERE user like 'dummy%'; user host dummy localhost dummy1 localhost dummy2 localhost -SELECT COUNT(*) FROM mysql.user; +SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%'; COUNT(*) -6 +3 **** On Slave **** -SELECT user,host FROM mysql.user WHERE user != 'root'; +SELECT user,host FROM mysql.user WHERE user like 'dummy%'; user host dummy localhost dummy1 localhost dummy2 localhost -SELECT COUNT(*) FROM mysql.user; +SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%'; COUNT(*) -6 +3 **** On Master **** DROP USER nonexisting@localhost; ERROR HY000: Operation DROP USER failed for 'nonexisting'@'localhost' DROP USER nonexisting@localhost, dummy@localhost; ERROR HY000: Operation DROP USER failed for 'nonexisting'@'localhost' DROP USER dummy1@localhost, dummy2@localhost; -SELECT user, host FROM mysql.user WHERE user != 'root'; +SELECT user, host FROM mysql.user WHERE user like 'dummy%'; user host -SELECT COUNT(*) FROM mysql.user; +SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%'; COUNT(*) -3 +0 **** On Slave **** -SELECT user,host FROM mysql.user WHERE user != 'root'; +SELECT user,host FROM mysql.user WHERE user like 'dummy%'; user host -SELECT COUNT(*) FROM mysql.user; +SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%'; COUNT(*) -3 +0 SHOW SLAVE STATUS; Slave_IO_State # Master_Host 127.0.0.1 @@ -48,7 +48,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 617 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -57,13 +57,13 @@ Slave_SQL_Running Yes Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table -Replicate_Ignore_Table +Replicate_Ignore_Table # Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 617 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -76,7 +76,7 @@ Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No -Last_IO_Errno 0 -Last_IO_Error +Last_IO_Errno # +Last_IO_Error # Last_SQL_Errno 0 Last_SQL_Error diff --git a/mysql-test/suite/rpl/r/rpl_idempotency.result b/mysql-test/suite/rpl/r/rpl_idempotency.result index f17fbd82c44..5a4052864ad 100644 --- a/mysql-test/suite/rpl/r/rpl_idempotency.result +++ b/mysql-test/suite/rpl/r/rpl_idempotency.result @@ -69,3 +69,158 @@ a Last_SQL_Error 0 DROP TABLE t1, t2; +select @@global.slave_exec_mode /* must be IDEMPOTENT */; +@@global.slave_exec_mode +IDEMPOTENT +create table ti1 (b int primary key) engine = innodb; +create table ti2 (a int primary key, b int, foreign key (b) references ti1(b)) +engine = innodb; +set foreign_key_checks=1 /* ensure the check */; +insert into ti1 values (1),(2),(3); +insert into ti2 set a=2, b=2; +select * from ti1 order by b /* must be (1),(2),(3) */; +b +1 +2 +3 +insert into ti2 set a=1, b=1; +select * from ti2 order by b /* must be (1,1) (2,2) */; +a b +1 1 +2 2 +set @save_binlog_format= @@session.binlog_format; +set @@session.binlog_format= row; +delete from ti1 where b=1; +select * from ti1 order by b /* must be (2),(3) */; +b +2 +3 +select * from ti1 order by b /* must stays as were on master (1),(2),(3) */; +b +1 +2 +3 +delete from ti1 where b=3; +insert into ti2 set a=3, b=3; +select * from ti2 order by b /* must be (1,1),(2,2) - not inserted */; +a b +1 1 +2 2 +set global slave_exec_mode='IDEMPOTENT'; +set global slave_exec_mode='STRICT'; +set global slave_exec_mode='IDEMPOTENT,STRICT'; +ERROR HY000: Ambiguous slave modes combination. +select @@global.slave_exec_mode /* must be STRICT */; +@@global.slave_exec_mode +STRICT +*** foreign keys errors as above now forces to stop +set foreign_key_checks=0; +drop table ti2, ti1; +create table ti1 (b int primary key) engine = innodb; +create table ti2 (a int primary key, b int, foreign key (b) references ti1(b)) +engine = innodb; +set foreign_key_checks=1 /* ensure the check */; +insert into ti1 values (1),(2),(3); +insert into ti2 set a=2, b=2; +select * from ti1 order by b /* must be (1),(2),(3) */; +b +1 +2 +3 +*** conspire future problem +insert into ti2 set a=1, b=1; +select * from ti2 order by b /* must be (1,1) (2,2) */; +a b +1 1 +2 2 +delete from ti1 where b=1 /* offending delete event */; +select * from ti1 order by b /* must be (2),(3) */; +b +2 +3 +*** slave must stop +Last_SQL_Error +0 +select * from ti1 order by b /* must be (1),(2),(3) - not deleted */; +b +1 +2 +3 +set foreign_key_checks= 0; +delete from ti2 where b=1; +set foreign_key_checks= 1; +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +set global slave_exec_mode='STRICT'; +*** conspire the following insert failure +*** conspire future problem +delete from ti1 where b=3; +insert into ti2 set a=3, b=3 /* offending write event */; +*** slave must stop +Last_SQL_Error +1452 +select * from ti2 order by b /* must be (2,2) */; +a b +2 2 +set foreign_key_checks= 0; +insert into ti1 set b=3; +set foreign_key_checks= 1; +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +set global slave_exec_mode='STRICT'; +select * from ti2 order by b /* must be (2,2),(3,3) */; +a b +2 2 +3 3 +*** other errors +*** conspiring query +insert into ti1 set b=1; +insert into ti1 set b=1 /* offending write event */; +*** slave must stop +Last_SQL_Error +1062 +set foreign_key_checks= 0; +delete from ti1 where b=1; +set foreign_key_checks= 1; +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +set global slave_exec_mode='STRICT'; +CREATE TABLE t1 (a INT PRIMARY KEY); +CREATE TABLE t2 (a INT); +INSERT INTO t1 VALUES (-1),(-2),(-3); +INSERT INTO t2 VALUES (-1),(-2),(-3); +DELETE FROM t1 WHERE a = -2; +DELETE FROM t2 WHERE a = -2; +DELETE FROM t1 WHERE a = -2; +*** slave must stop +Last_SQL_Error +1032 +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +set global slave_exec_mode='STRICT'; +DELETE FROM t2 WHERE a = -2; +*** slave must stop +Last_SQL_Error +0 +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +set global slave_exec_mode='STRICT'; +UPDATE t1 SET a = 1 WHERE a = -1; +UPDATE t2 SET a = 1 WHERE a = -1; +UPDATE t1 SET a = 1 WHERE a = -1; +*** slave must stop +Last_SQL_Error +1032 +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +set global slave_exec_mode='STRICT'; +UPDATE t2 SET a = 1 WHERE a = -1; +*** slave must stop +Last_SQL_Error +0 +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +set global slave_exec_mode='STRICT'; +set @@session.binlog_format= @save_binlog_format; +drop table t1,t2,ti2,ti1; +*** end of tests diff --git a/mysql-test/suite/rpl/r/rpl_ignore_table.result b/mysql-test/suite/rpl/r/rpl_ignore_table.result index e7200b31212..cdc3f5e9579 100644 --- a/mysql-test/suite/rpl/r/rpl_ignore_table.result +++ b/mysql-test/suite/rpl/r/rpl_ignore_table.result @@ -115,6 +115,7 @@ GRANT INSERT, INSERT (a), UPDATE (a), REFERENCES (a) ON `test`.`t4` TO 'mysqltes show grants for mysqltest4@localhost; Grants for mysqltest4@localhost GRANT USAGE ON *.* TO 'mysqltest4'@'localhost' IDENTIFIED BY PASSWORD '*196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7' +set global slave_exec_mode='IDEMPOTENT'; drop table t1, t4, mysqltest2.t2; drop database mysqltest2; delete from mysql.user where user like "mysqltest%"; @@ -132,6 +133,7 @@ INSERT INTO t5 (word) VALUES ('TEST’'); SELECT HEX(word) FROM t5; HEX(word) 54455354E28099 +set @@global.slave_exec_mode= default; SELECT HEX(word) FROM t5; HEX(word) 54455354E28099 diff --git a/mysql-test/suite/rpl/r/rpl_init_slave.result b/mysql-test/suite/rpl/r/rpl_init_slave.result index 740c918976c..5ff72e57f0e 100644 --- a/mysql-test/suite/rpl/r/rpl_init_slave.result +++ b/mysql-test/suite/rpl/r/rpl_init_slave.result @@ -4,6 +4,9 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +set global max_connections=151; +stop slave; +start slave; show variables like 'init_slave'; Variable_name Value init_slave set global max_connections=500 diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result index 0e11d132cc4..f8220ca25d3 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result @@ -835,108 +835,158 @@ master-bin.000001 # Format_desc 1 # Server ver: # master-bin.000001 # Query 1 # CREATE DATABASE test_rpl master-bin.000001 # Query 1 # use `test_rpl`; CREATE TABLE t1 (a int auto_increment not null, b char(254), PRIMARY KEY(a)) ENGINE=innodb master-bin.000001 # Query 1 # use `test_rpl`; CREATE TABLE t2 (a int auto_increment not null, b char(254), PRIMARY KEY(a)) ENGINE=innodb +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 't1, text 1') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(2, 't1, text 2') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t2 VALUES(1, 't2, text 1') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 WHERE a = 1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Table_map 1 # table_id: # (test_rpl.t2) master-bin.000001 # Delete_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 't1, text 1') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Table_map 1 # table_id: # (test_rpl.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t2 SELECT * FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t2 VALUES (1, 't1, text 1') ON DUPLICATE KEY UPDATE b = 't2, text 1' master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 WHERE a = 2 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 WHERE a = 2 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Begin_load_query 1 # ;file_id=#;block_len=# master-bin.000001 # Execute_load_query 1 # use `test_rpl`; LOAD DATA INFILE '../tmp/rpl_mixed.dat' INTO TABLE t1 FIELDS TERMINATED BY '|' ;file_id=# master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 't1, text 1') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(2, 't1, text 2') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(3, 't1, text 3') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; REPLACE INTO t1 VALUES(1, 't1, text 11') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Table_map 1 # table_id: # (test_rpl.t1) master-bin.000001 # Update_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; REPLACE INTO t1 SET a=3, b='t1, text 33' master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 WHERE a = 2 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 't1, text 1') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 'CCC') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(2, 'DDD') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t2 VALUES(1, 'DDD') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t2 VALUES(2, 'CCC') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 't1, text 1') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t2 VALUES(1, 't2, text 1') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 't1, text 1') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; TRUNCATE t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 't1, text 1') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t2 VALUES(1, 't2, text 1') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; UPDATE t1 SET b = 't1, text 1 updated' WHERE a = 1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; UPDATE t1, t2 SET t1.b = 'test', t2.b = 'test' master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # use `test_rpl`; BEGIN @@ -952,10 +1002,13 @@ master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES (6, 'after s master-bin.000001 # Table_map 1 # table_id: # (test_rpl.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 WHERE a = 7 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # use `test_rpl`; CREATE USER 'user_test_rpl'@'localhost' IDENTIFIED BY PASSWORD '*1111111111111111111111111111111111111111' @@ -964,6 +1017,7 @@ master-bin.000001 # Query 1 # use `test_rpl`; REVOKE SELECT ON *.* FROM 'user_te master-bin.000001 # Query 1 # use `test_rpl`; SET PASSWORD FOR 'user_test_rpl'@'localhost'='*0000000000000000000000000000000000000000' master-bin.000001 # Query 1 # use `test_rpl`; RENAME USER 'user_test_rpl'@'localhost' TO 'user_test_rpl_2'@'localhost' master-bin.000001 # Query 1 # use `test_rpl`; DROP USER 'user_test_rpl_2'@'localhost' +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(100, 'test') master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # use `test_rpl`; ANALYZE TABLE t1 @@ -977,50 +1031,65 @@ master-bin.000001 # Query 1 # use `test_rpl`; CREATE DEFINER=`root`@`localhost` BEGIN UPDATE t1 SET b = UUID() WHERE a = 202; END +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(201, 'test 201') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; UPDATE t1 SET b = 'test' WHERE a = 201 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(202, 'test 202') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Table_map 1 # table_id: # (test_rpl.t1) master-bin.000001 # Update_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 WHERE a = 202 master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # use `test_rpl`; ALTER PROCEDURE p1 COMMENT 'p1' master-bin.000001 # Query 1 # use `test_rpl`; DROP PROCEDURE p1 master-bin.000001 # Query 1 # use `test_rpl`; DROP PROCEDURE p2 +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # use `test_rpl`; CREATE DEFINER=`root`@`localhost` TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN INSERT INTO t2 SET a = NEW.a, b = NEW.b; END +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Table_map 1 # table_id: # (test_rpl.t1) master-bin.000001 # Table_map 1 # table_id: # (test_rpl.t2) master-bin.000001 # Write_rows 1 # table_id: # master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # use `test_rpl`; DROP TRIGGER tr1 master-bin.000001 # Query 1 # use `test_rpl`; GRANT EVENT ON *.* TO 'root'@'localhost' +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 'test1') master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # use `test_rpl`; CREATE EVENT e1 ON SCHEDULE EVERY '1' SECOND COMMENT 'e_second_comment' DO DELETE FROM t1 master-bin.000001 # Query 1 # use `test_rpl`; ALTER EVENT e1 RENAME TO e2 master-bin.000001 # Query 1 # use `test_rpl`; DROP EVENT e2 +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 'test1') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(2, 'test2') master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # use `test_rpl`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS SELECT * FROM t1 WHERE a = 1 @@ -1028,8 +1097,10 @@ master-bin.000001 # Query 1 # use `test_rpl`; CREATE ALGORITHM=UNDEFINED DEFINER master-bin.000001 # Query 1 # use `test_rpl`; ALTER ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS SELECT * FROM t1 WHERE a = 2 master-bin.000001 # Query 1 # use `test_rpl`; DROP VIEW v1 master-bin.000001 # Query 1 # use `test_rpl`; DROP VIEW v2 +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # drop database test_rpl; diff --git a/mysql-test/suite/rpl/r/rpl_invoked_features.result b/mysql-test/suite/rpl/r/rpl_invoked_features.result index 18434d8087e..aed1dcdbb47 100644 --- a/mysql-test/suite/rpl/r/rpl_invoked_features.result +++ b/mysql-test/suite/rpl/r/rpl_invoked_features.result @@ -116,23 +116,23 @@ t12 t13 t2 t3 -SELECT table_name FROM information_schema.views WHERE table_schema='test' order by table_name; +SELECT table_name FROM information_schema.views WHERE table_schema='test' ORDER BY table_name; table_name v1 v11 -SELECT trigger_name, event_manipulation, event_object_table FROM information_schema.triggers WHERE trigger_schema='test' order by trigger_name; +SELECT trigger_name, event_manipulation, event_object_table FROM information_schema.triggers WHERE trigger_schema='test' ORDER BY trigger_name; trigger_name event_manipulation event_object_table t11_tr1 INSERT t11 t11_tr2 UPDATE t11 t1_tr1 INSERT t1 t1_tr2 UPDATE t1 -SELECT routine_type, routine_name FROM information_schema.routines WHERE routine_schema='test' order by routine_name; +SELECT routine_type, routine_name FROM information_schema.routines WHERE routine_schema='test' ORDER BY routine_name; routine_type routine_name FUNCTION f1 FUNCTION f2 PROCEDURE p1 PROCEDURE p11 -SELECT event_name, status FROM information_schema.events WHERE event_schema='test' order by event_name; +SELECT event_name, status FROM information_schema.events WHERE event_schema='test' ORDER BY event_name; event_name status e1 DISABLED e11 DISABLED @@ -276,23 +276,23 @@ t12 t13 t2 t3 -SELECT table_name FROM information_schema.views WHERE table_schema='test' order by table_name; +SELECT table_name FROM information_schema.views WHERE table_schema='test' ORDER BY table_name; table_name v1 v11 -SELECT trigger_name, event_manipulation, event_object_table FROM information_schema.triggers WHERE trigger_schema='test' order by trigger_name; +SELECT trigger_name, event_manipulation, event_object_table FROM information_schema.triggers WHERE trigger_schema='test' ORDER BY trigger_name; trigger_name event_manipulation event_object_table t11_tr1 INSERT t11 t11_tr2 UPDATE t11 t1_tr1 INSERT t1 t1_tr2 UPDATE t1 -SELECT routine_type, routine_name FROM information_schema.routines WHERE routine_schema='test' order by routine_name; +SELECT routine_type, routine_name FROM information_schema.routines WHERE routine_schema='test' ORDER BY routine_name; routine_type routine_name FUNCTION f1 FUNCTION f2 PROCEDURE p1 PROCEDURE p11 -SELECT event_name, status FROM information_schema.events WHERE event_schema='test' order by event_name; +SELECT event_name, status FROM information_schema.events WHERE event_schema='test' ORDER BY event_name; event_name status e1 SLAVESIDE_DISABLED e11 SLAVESIDE_DISABLED diff --git a/mysql-test/suite/rpl/r/rpl_load_from_master.result b/mysql-test/suite/rpl/r/rpl_load_from_master.result index 08b45ec1db0..e1c2ecb35be 100644 --- a/mysql-test/suite/rpl/r/rpl_load_from_master.result +++ b/mysql-test/suite/rpl/r/rpl_load_from_master.result @@ -30,13 +30,11 @@ drop database mysqltest2; set sql_log_bin = 0; create database mysqltest2; create database mysqltest; -show databases; -Database -information_schema +show databases like 'mysql%'; +Database (mysql%) mysql mysqltest mysqltest2 -test create table mysqltest2.t1(n int, s char(20))ENGINE=MyISAM; create table mysqltest2.t2(n int, s text)ENGINE=MyISAM; insert into mysqltest2.t1 values (1, 'one'), (2, 'two'), (3, 'three'); @@ -47,11 +45,9 @@ insert into mysqltest.t1 values (1, 'one test'), (2, 'two test'), (3, 'three tes insert into mysqltest.t2 values (11, 'eleven test'), (12, 'twelve test'), (13, 'thirteen test'); set sql_log_bin = 1; -show databases; -Database -information_schema +show databases like 'mysql%'; +Database (mysql%) mysql -test create database mysqltest2; create table mysqltest2.t1(n int, s char(20))ENGINE=MyISAM; insert into mysqltest2.t1 values (1, 'original foo.t1'); @@ -66,14 +62,12 @@ insert into mysqltest.t1 values (1, 'original bar.t1'); create table mysqltest.t3(n int, s char(20))ENGINE=MyISAM; insert into mysqltest.t3 values (1, 'original bar.t3'); load data from master; -show databases; -Database -information_schema +show databases like 'mysql%'; +Database (mysql%) mysql mysqltest mysqltest2 mysqltest3 -test use mysqltest2; show tables; Tables_in_mysqltest2 diff --git a/mysql-test/suite/rpl/r/rpl_loaddata_map.result b/mysql-test/suite/rpl/r/rpl_loaddata_map.result new file mode 100644 index 00000000000..e6ddc1ebedc --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_loaddata_map.result @@ -0,0 +1,26 @@ +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; +create table t2 (id int not null primary key auto_increment); +select @@session.read_buffer_size - @@session.max_allowed_packet > 0 ; +@@session.read_buffer_size - @@session.max_allowed_packet > 0 +1 +load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2; +select count(*) from t2 /* 5 000 */; +count(*) +5000 +show binlog events in 'master-bin.000002' from 106; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000002 106 Query 1 # use `test`; create table t2 (id int not null primary key auto_increment) +master-bin.000002 229 Begin_load_query 1 # ;file_id=#;block_len=8192 +master-bin.000002 8444 Append_block 1 # ;file_id=#;block_len=8192 +master-bin.000002 16659 Append_block 1 # ;file_id=#;block_len=7509 +master-bin.000002 24191 Execute_load_query 1 # use `test`; load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2 ;file_id=# +select count(*) from t2 /* 5 000 */; +count(*) +5000 +drop table t1, t2; +end of the tests diff --git a/mysql-test/suite/rpl/r/rpl_log_pos.result b/mysql-test/suite/rpl/r/rpl_log_pos.result index 0f3552af5bc..e0c4dedde10 100644 --- a/mysql-test/suite/rpl/r/rpl_log_pos.result +++ b/mysql-test/suite/rpl/r/rpl_log_pos.result @@ -6,7 +6,7 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; show master status; File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 106 <Binlog_Ignore_DB> +master-bin.000001 # <Binlog_Do_DB> <Binlog_Ignore_DB> stop slave; change master to master_log_pos=75; SHOW SLAVE STATUS; @@ -16,7 +16,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 75 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -31,7 +31,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 75 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -91,12 +91,12 @@ Last_SQL_Errno 0 Last_SQL_Error show master status; File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 106 <Binlog_Ignore_DB> +master-bin.000001 # <Binlog_Do_DB> <Binlog_Ignore_DB> create table if not exists t1 (n int); drop table if exists t1; create table t1 (n int); insert into t1 values (1),(2),(3); -change master to master_log_pos=106; +change master to master_log_pos=4; start slave; select * from t1 ORDER BY n; n diff --git a/mysql-test/suite/rpl/r/rpl_rotate_logs.result b/mysql-test/suite/rpl/r/rpl_rotate_logs.result index 2282067ddfd..6314a9a61fb 100644 --- a/mysql-test/suite/rpl/r/rpl_rotate_logs.result +++ b/mysql-test/suite/rpl/r/rpl_rotate_logs.result @@ -21,7 +21,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 60 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 556 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -36,7 +36,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 556 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -63,9 +63,9 @@ insert into t2 values (34),(67),(123); flush logs; show binary logs; Log_name File_size -master-bin.000001 600 -master-bin.000002 371 -master-bin.000003 106 +master-bin.000001 # +master-bin.000002 # +master-bin.000003 # create table t3 select * from temp_table; select * from t3; a @@ -78,21 +78,22 @@ set global sql_slave_skip_counter=1; start slave; purge master logs to 'master-bin.000002'; show master logs; -Log_name File_size -master-bin.000002 371 -master-bin.000003 415 +Log_name master-bin.000002 +File_size # +Log_name master-bin.000003 +File_size # purge binary logs to 'master-bin.000002'; show binary logs; Log_name File_size -master-bin.000002 371 -master-bin.000003 415 +master-bin.000002 # +master-bin.000003 # select @time_for_purge:=DATE_ADD(UPDATE_TIME, INTERVAL 1 SECOND) from information_schema.tables where TABLE_SCHEMA="test" and TABLE_NAME="t2"; purge master logs before (@time_for_purge); show binary logs; Log_name File_size -master-bin.000003 415 +master-bin.000003 # insert into t2 values (65); SHOW SLAVE STATUS; Slave_IO_State # @@ -101,7 +102,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 60 Master_Log_File master-bin.000003 -Read_Master_Log_Pos 504 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000003 @@ -116,7 +117,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 504 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -149,12 +150,12 @@ count(*) create table t4 select * from temp_table; show binary logs; Log_name File_size -master-bin.000003 4193 -master-bin.000004 4198 -master-bin.000005 2040 +master-bin.000003 # +master-bin.000004 # +master-bin.000005 # show master status; File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000005 2040 +master-bin.000005 # <Binlog_Do_DB> <Binlog_Ignore_DB> select * from t4; a testing temporary tables part 2 @@ -165,7 +166,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 60 Master_Log_File master-bin.000005 -Read_Master_Log_Pos 2040 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000005 @@ -180,7 +181,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 2040 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/suite/rpl/r/rpl_row_basic_11bugs.result b/mysql-test/suite/rpl/r/rpl_row_basic_11bugs.result index c3fd663fad8..f49c23248e5 100644 --- a/mysql-test/suite/rpl/r/rpl_row_basic_11bugs.result +++ b/mysql-test/suite/rpl/r/rpl_row_basic_11bugs.result @@ -257,6 +257,7 @@ SELECT * FROM t1 ORDER BY a; a b 2 master,slave 5 slave +set @@global.slave_exec_mode= 'IDEMPOTENT'; **** On Master **** UPDATE t1 SET a = 5, b = 'master' WHERE a = 1; SELECT * FROM t1 ORDER BY a; @@ -264,6 +265,7 @@ a b 2 master,slave 5 master **** On Slave **** +set @@global.slave_exec_mode= default; Last_SQL_Error SELECT * FROM t1 ORDER BY a; diff --git a/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result b/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result index 2efe3a3e486..22284a26412 100644 --- a/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result +++ b/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result @@ -370,6 +370,7 @@ C1 C2 1 3 2 6 3 9 +set @@global.slave_exec_mode= 'IDEMPOTENT'; --- on master: new values inserted --- INSERT INTO t7 VALUES (1,2), (2,4), (3,6); SELECT * FROM t7 ORDER BY C1; @@ -377,6 +378,7 @@ C1 C2 1 2 2 4 3 6 +set @@global.slave_exec_mode= default; --- on slave: old values should be overwritten by replicated values --- SELECT * FROM t7 ORDER BY C1; C1 C2 @@ -406,8 +408,10 @@ a b c 2 4 6 3 6 9 99 99 99 +set @@global.slave_exec_mode= 'IDEMPOTENT'; --- on master --- INSERT INTO t8 VALUES (2,4,8); +set @@global.slave_exec_mode= default; --- on slave --- SELECT * FROM t8 ORDER BY a; a b c @@ -426,10 +430,12 @@ START SLAVE; **** On Master **** INSERT INTO t1 VALUES ('K','K'), ('L','L'), ('M','M'); **** On Master **** +set @@global.slave_exec_mode= 'IDEMPOTENT'; DELETE FROM t1 WHERE C1 = 'L'; DELETE FROM t1; SELECT COUNT(*) FROM t1 ORDER BY c1,c2; COUNT(*) 0 +set @@global.slave_exec_mode= default; Last_SQL_Error 0 SELECT COUNT(*) FROM t1 ORDER BY c1,c2; diff --git a/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result b/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result index fc78abfbe2e..f7b9e5d627a 100644 --- a/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result +++ b/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result @@ -370,6 +370,7 @@ C1 C2 1 3 2 6 3 9 +set @@global.slave_exec_mode= 'IDEMPOTENT'; --- on master: new values inserted --- INSERT INTO t7 VALUES (1,2), (2,4), (3,6); SELECT * FROM t7 ORDER BY C1; @@ -377,6 +378,7 @@ C1 C2 1 2 2 4 3 6 +set @@global.slave_exec_mode= default; --- on slave: old values should be overwritten by replicated values --- SELECT * FROM t7 ORDER BY C1; C1 C2 @@ -406,8 +408,10 @@ a b c 2 4 6 3 6 9 99 99 99 +set @@global.slave_exec_mode= 'IDEMPOTENT'; --- on master --- INSERT INTO t8 VALUES (2,4,8); +set @@global.slave_exec_mode= default; --- on slave --- SELECT * FROM t8 ORDER BY a; a b c @@ -426,10 +430,12 @@ START SLAVE; **** On Master **** INSERT INTO t1 VALUES ('K','K'), ('L','L'), ('M','M'); **** On Master **** +set @@global.slave_exec_mode= 'IDEMPOTENT'; DELETE FROM t1 WHERE C1 = 'L'; DELETE FROM t1; SELECT COUNT(*) FROM t1 ORDER BY c1,c2; COUNT(*) 0 +set @@global.slave_exec_mode= default; Last_SQL_Error 0 SELECT COUNT(*) FROM t1 ORDER BY c1,c2; diff --git a/mysql-test/suite/rpl/r/rpl_row_charset_innodb.result b/mysql-test/suite/rpl/r/rpl_row_charset_innodb.result index eb1dc585457..4edc224135e 100644 --- a/mysql-test/suite/rpl/r/rpl_row_charset_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_row_charset_innodb.result @@ -118,37 +118,49 @@ master-bin.000001 # Query # # create database mysqltest3 master-bin.000001 # Query # # drop database mysqltest3 master-bin.000001 # Query # # create database mysqltest3 master-bin.000001 # Query # # use `mysqltest2`; create table t1 (a int auto_increment primary key, b varchar(100))engine=innodb +master-bin.000001 # Query # # use `mysqltest2`; BEGIN master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `mysqltest2`; BEGIN master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `mysqltest2`; BEGIN master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `mysqltest2`; BEGIN master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `mysqltest2`; BEGIN master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `mysqltest2`; BEGIN master-bin.000001 # Query # # use `mysqltest2`; truncate table t1 master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `mysqltest2`; BEGIN master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `mysqltest2`; BEGIN master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `mysqltest2`; BEGIN master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `mysqltest2`; BEGIN master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `mysqltest2`; BEGIN master-bin.000001 # Query # # use `mysqltest2`; truncate table t1 master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `mysqltest2`; BEGIN master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ diff --git a/mysql-test/suite/rpl/r/rpl_row_create_table.result b/mysql-test/suite/rpl/r/rpl_row_create_table.result index 84c36278e1d..ba5a13a57bf 100644 --- a/mysql-test/suite/rpl/r/rpl_row_create_table.result +++ b/mysql-test/suite/rpl/r/rpl_row_create_table.result @@ -127,7 +127,7 @@ NULL 5 10 NULL 6 12 CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3; ERROR 23000: Duplicate entry '2' for key 'b' -SHOW BINLOG EVENTS FROM 1100; +SHOW BINLOG EVENTS FROM 1374; Log_name Pos Event_type Server_id End_log_pos Info CREATE TABLE t7 (a INT, b INT UNIQUE); INSERT INTO t7 SELECT a,b FROM tt3; @@ -137,11 +137,11 @@ a b 1 2 2 4 3 6 -SHOW BINLOG EVENTS FROM 1100; +SHOW BINLOG EVENTS FROM 1374; Log_name Pos Event_type Server_id End_log_pos Info -# 1100 Query # 1200 use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE) -# 1200 Table_map # 1242 table_id: # (test.t7) -# 1242 Write_rows # 1298 table_id: # flags: STMT_END_F +# 1374 Query # 1474 use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE) +# 1474 Table_map # 1516 table_id: # (test.t7) +# 1516 Write_rows # 1572 table_id: # flags: STMT_END_F SELECT * FROM t7 ORDER BY a,b; a b 1 2 @@ -154,10 +154,10 @@ INSERT INTO t7 SELECT a,b FROM tt4; ROLLBACK; Warnings: Warning 1196 Some non-transactional changed tables couldn't be rolled back -SHOW BINLOG EVENTS FROM 1298; +SHOW BINLOG EVENTS FROM 1572; Log_name Pos Event_type Server_id End_log_pos Info -# 1298 Table_map # 1340 table_id: # (test.t7) -# 1340 Write_rows # 1396 table_id: # flags: STMT_END_F +# 1572 Table_map # 1614 table_id: # (test.t7) +# 1614 Write_rows # 1670 table_id: # flags: STMT_END_F SELECT * FROM t7 ORDER BY a,b; a b 1 2 @@ -192,10 +192,10 @@ Create Table CREATE TABLE `t9` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 -SHOW BINLOG EVENTS FROM 1396; +SHOW BINLOG EVENTS FROM 1670; Log_name Pos Event_type Server_id End_log_pos Info -# 1396 Query # 1482 use `test`; CREATE TABLE t8 LIKE t4 -# 1482 Query # 1621 use `test`; CREATE TABLE `t9` ( +# 1670 Query # 1756 use `test`; CREATE TABLE t8 LIKE t4 +# 1756 Query # 1895 use `test`; CREATE TABLE `t9` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) @@ -398,14 +398,15 @@ SELECT * FROM t2 ORDER BY a; a SHOW BINLOG EVENTS FROM 637; Log_name Pos Event_type Server_id End_log_pos Info -# 637 Query # 717 use `test`; TRUNCATE TABLE t2 -# 717 Xid # 744 COMMIT /* XID */ -# 744 Query # 812 use `test`; BEGIN -# 812 Table_map # 853 table_id: # (test.t2) -# 853 Write_rows # 897 table_id: # flags: STMT_END_F -# 897 Table_map # 938 table_id: # (test.t2) -# 938 Write_rows # 977 table_id: # flags: STMT_END_F -# 977 Query # 1048 use `test`; ROLLBACK +# 637 Query # 705 use `test`; BEGIN +# 705 Query # 785 use `test`; TRUNCATE TABLE t2 +# 785 Xid # 812 COMMIT /* XID */ +# 812 Query # 880 use `test`; BEGIN +# 880 Table_map # 921 table_id: # (test.t2) +# 921 Write_rows # 965 table_id: # flags: STMT_END_F +# 965 Table_map # 1006 table_id: # (test.t2) +# 1006 Write_rows # 1045 table_id: # flags: STMT_END_F +# 1045 Query # 1116 use `test`; ROLLBACK SELECT * FROM t2 ORDER BY a; a DROP TABLE t1,t2; diff --git a/mysql-test/suite/rpl/r/rpl_row_log_innodb.result b/mysql-test/suite/rpl/r/rpl_row_log_innodb.result index 9ed35f34dc5..e08c47558a0 100644 --- a/mysql-test/suite/rpl/r/rpl_row_log_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_row_log_innodb.result @@ -20,11 +20,13 @@ show binlog events; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4 master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=InnoDB +master-bin.000001 # Query 1 # use `test`; BEGIN master-bin.000001 # Table_map 1 # table_id: # (test.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Xid 1 # COMMIT /* XID */ master-bin.000001 # Query 1 # use `test`; drop table t1 master-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)ENGINE=InnoDB +master-bin.000001 # Query 1 # use `test`; BEGIN master-bin.000001 # Table_map 1 # table_id: # (test.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Xid 1 # COMMIT /* XID */ @@ -34,10 +36,10 @@ master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_in show binlog events from 106 limit 2; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=InnoDB -master-bin.000001 # Table_map 1 # table_id: # (test.t1) +master-bin.000001 # Query 1 # use `test`; BEGIN show binlog events from 106 limit 2,1; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (test.t1) flush logs; create table t3 (a int)ENGINE=InnoDB; select * from t1 order by 1 asc; @@ -194,11 +196,13 @@ insert into t2 values (1); show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; drop table t1 master-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ @@ -208,27 +212,30 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000002 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4 master-bin.000002 # Query 1 # use `test`; create table t3 (a int)ENGINE=InnoDB master-bin.000002 # Query 1 # use `test`; create table t2 (n int)ENGINE=InnoDB +master-bin.000002 # Query 1 # use `test`; BEGIN master-bin.000002 # Table_map 1 # table_id: # (test.t2) master-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000002 # Xid 1 # COMMIT /* XID */ show binary logs; Log_name File_size -master-bin.000001 1320 -master-bin.000002 406 +master-bin.000001 1456 +master-bin.000002 474 start slave; show binary logs; Log_name File_size -slave-bin.000001 1418 -slave-bin.000002 307 +slave-bin.000001 1536 +slave-bin.000002 366 show binlog events in 'slave-bin.000001' from 4; Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000001 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4 slave-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=InnoDB +slave-bin.000001 # Query 1 # BEGIN slave-bin.000001 # Table_map 1 # table_id: # (test.t1) slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F slave-bin.000001 # Xid 1 # COMMIT /* XID */ slave-bin.000001 # Query 1 # use `test`; drop table t1 slave-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)ENGINE=InnoDB +slave-bin.000001 # Query 1 # BEGIN slave-bin.000001 # Table_map 1 # table_id: # (test.t1) slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F slave-bin.000001 # Xid 1 # COMMIT /* XID */ @@ -238,6 +245,7 @@ show binlog events in 'slave-bin.000002' from 4; Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000002 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4 slave-bin.000002 # Query 1 # use `test`; create table t2 (n int)ENGINE=InnoDB +slave-bin.000002 # Query 1 # BEGIN slave-bin.000002 # Table_map 1 # table_id: # (test.t2) slave-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F slave-bin.000002 # Xid 1 # COMMIT /* XID */ @@ -248,7 +256,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000002 -Read_Master_Log_Pos 406 +Read_Master_Log_Pos 474 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000002 @@ -263,7 +271,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 406 +Exec_Master_Log_Pos 474 Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/suite/rpl/r/rpl_row_max_relay_size.result b/mysql-test/suite/rpl/r/rpl_row_max_relay_size.result index 06266f1de82..392f5904233 100644 --- a/mysql-test/suite/rpl/r/rpl_row_max_relay_size.result +++ b/mysql-test/suite/rpl/r/rpl_row_max_relay_size.result @@ -30,7 +30,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 60268 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -45,7 +45,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 60268 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -78,7 +78,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 60268 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -93,7 +93,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 60268 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -126,7 +126,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 60268 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -141,7 +141,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 60268 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -171,7 +171,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File -Read_Master_Log_Pos 4 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File @@ -186,7 +186,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 0 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -217,7 +217,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 60354 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -232,7 +232,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 60354 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -261,7 +261,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 60430 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -276,7 +276,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 60430 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -295,10 +295,8 @@ Last_SQL_Errno 0 Last_SQL_Error flush logs; show master status; -File master-bin.000002 -Position 106 -Binlog_Do_DB <Binlog_Ignore_DB> -Binlog_Ignore_DB +File Position Binlog_Do_DB Binlog_Ignore_DB +master-bin.000002 # <Binlog_Do_DB> <Binlog_Ignore_DB> set global max_binlog_size= @my_max_binlog_size; # # End of 4.1 tests diff --git a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result index e2df1459ac0..1d5b118d822 100644 --- a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result +++ b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result @@ -155,13 +155,15 @@ c1 c3 c4 c5 /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; +ROLLBACK/*!*/; use test/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -CREATE TABLE t3(c1 INT NOT NULL PRIMARY KEY, c2 LONGBLOB, c3 TIMESTAMP, c4 TEXT, c5 FLOAT)/*!*/; +CREATE TABLE t3(c1 INT NOT NULL PRIMARY KEY, c2 LONGBLOB, c3 TIMESTAMP, c4 TEXT, c5 FLOAT) +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -178,13 +180,17 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -DROP TABLE IF EXISTS t1,t2,t3/*!*/; +DROP TABLE IF EXISTS t1,t2,t3 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -CREATE TABLE t1(word VARCHAR(20))/*!*/; +CREATE TABLE t1(word VARCHAR(20)) +/*!*/; SET TIMESTAMP=1000000000/*!*/; -CREATE TABLE t2(id INT AUTO_INCREMENT NOT NULL PRIMARY KEY)/*!*/; +CREATE TABLE t2(id INT AUTO_INCREMENT NOT NULL PRIMARY KEY) +/*!*/; SET TIMESTAMP=1000000000/*!*/; -CREATE TABLE t3(c1 INT NOT NULL PRIMARY KEY, c2 LONGBLOB, c3 TIMESTAMP, c4 TEXT, c5 FLOAT)/*!*/; +CREATE TABLE t3(c1 INT NOT NULL PRIMARY KEY, c2 LONGBLOB, c3 TIMESTAMP, c4 TEXT, c5 FLOAT) +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -279,13 +285,17 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -DROP TABLE IF EXISTS t1,t2,t3/*!*/; +DROP TABLE IF EXISTS t1,t2,t3 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -CREATE TABLE t1(word VARCHAR(20))/*!*/; +CREATE TABLE t1(word VARCHAR(20)) +/*!*/; SET TIMESTAMP=1000000000/*!*/; -CREATE TABLE t2(id INT AUTO_INCREMENT NOT NULL PRIMARY KEY)/*!*/; +CREATE TABLE t2(id INT AUTO_INCREMENT NOT NULL PRIMARY KEY) +/*!*/; SET TIMESTAMP=1000000000/*!*/; -CREATE TABLE t3(c1 INT NOT NULL PRIMARY KEY, c2 LONGBLOB, c3 TIMESTAMP, c4 TEXT, c5 FLOAT)/*!*/; +CREATE TABLE t3(c1 INT NOT NULL PRIMARY KEY, c2 LONGBLOB, c3 TIMESTAMP, c4 TEXT, c5 FLOAT) +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; @@ -295,13 +305,15 @@ ROLLBACK /* added by mysqlbinlog */; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; +ROLLBACK/*!*/; use test/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -CREATE TABLE t3(c1 INT NOT NULL PRIMARY KEY, c2 LONGBLOB, c3 TIMESTAMP, c4 TEXT, c5 FLOAT)/*!*/; +CREATE TABLE t3(c1 INT NOT NULL PRIMARY KEY, c2 LONGBLOB, c3 TIMESTAMP, c4 TEXT, c5 FLOAT) +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; diff --git a/mysql-test/suite/rpl/r/rpl_row_mystery22.result b/mysql-test/suite/rpl/r/rpl_row_mystery22.result index bcf65e4ede3..5e42a89d741 100644 --- a/mysql-test/suite/rpl/r/rpl_row_mystery22.result +++ b/mysql-test/suite/rpl/r/rpl_row_mystery22.result @@ -5,6 +5,7 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; create table t1(n int auto_increment primary key, s char(10)); +set @@global.slave_exec_mode= 'IDEMPOTENT'; insert into t1 values (2,'old'); insert into t1 values(NULL,'new'); insert into t1 values(NULL,'new'); @@ -28,3 +29,4 @@ n s 1 new 3 new drop table t1; +set @@global.slave_exec_mode= default; diff --git a/mysql-test/suite/rpl/r/rpl_row_reset_slave.result b/mysql-test/suite/rpl/r/rpl_row_reset_slave.result index fd23e254072..6126ec4bacc 100644 --- a/mysql-test/suite/rpl/r/rpl_row_reset_slave.result +++ b/mysql-test/suite/rpl/r/rpl_row_reset_slave.result @@ -11,7 +11,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 106 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -26,7 +26,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 106 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -52,7 +52,7 @@ Master_User test Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 106 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -67,7 +67,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 106 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -92,7 +92,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File -Read_Master_Log_Pos 4 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File @@ -107,7 +107,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 0 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -132,7 +132,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 106 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -147,7 +147,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 106 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result index a8e1c8602e0..6859a406b16 100644 --- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result +++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result @@ -37,6 +37,7 @@ ALTER TABLE t8 ADD e1 INT NOT NULL DEFAULT 0, ADD e2 INT NOT NULL DEFAULT 0, ADD e3 INT NOT NULL DEFAULT 0, ADD e4 INT NOT NULL DEFAULT 0, ADD e5 INT NOT NULL DEFAULT 0, ADD e6 INT NOT NULL DEFAULT 0, ADD e7 INT NOT NULL DEFAULT 0, ADD e8 INT NOT NULL DEFAULT 0; +set @@global.slave_exec_mode= 'IDEMPOTENT'; INSERT INTO t1_int VALUES (2, 4, 4711); INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar'); INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01'); @@ -60,6 +61,7 @@ a b 1 2 2 5 **** On Slave **** +set @@global.slave_exec_mode= default; SELECT a,b,x FROM t1_int ORDER BY a; a b x 1 2 42 @@ -123,7 +125,7 @@ Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 1364 -Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef. Field 'x' doesn't have a default value +Last_Error <Last_Error> Skip_Counter 0 Exec_Master_Log_Pos # Relay_Log_Space # @@ -139,9 +141,9 @@ Master_SSL_Key Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 -Last_IO_Error +Last_IO_Error <Last_IO_Error> Last_SQL_Errno 1364 -Last_SQL_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef. Field 'x' doesn't have a default value +Last_SQL_Error <Last_SQL_Error> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; INSERT INTO t9 VALUES (2); @@ -174,7 +176,7 @@ Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 0 -Last_Error +Last_Error <Last_Error> Skip_Counter 0 Exec_Master_Log_Pos # Relay_Log_Space # @@ -190,9 +192,9 @@ Master_SSL_Key Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 -Last_IO_Error +Last_IO_Error <Last_IO_Error> Last_SQL_Errno 0 -Last_SQL_Error +Last_SQL_Error <Last_SQL_Error> INSERT INTO t9 VALUES (4); INSERT INTO t4 VALUES (4); SHOW SLAVE STATUS; @@ -215,7 +217,7 @@ Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 1535 -Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 3, test.t4 has type 4 +Last_Error <Last_Error> Skip_Counter 0 Exec_Master_Log_Pos # Relay_Log_Space # @@ -231,9 +233,9 @@ Master_SSL_Key Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 -Last_IO_Error +Last_IO_Error <Last_IO_Error> Last_SQL_Errno 1535 -Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 3, test.t4 has type 4 +Last_SQL_Error <Last_SQL_Error> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; INSERT INTO t9 VALUES (5); @@ -258,7 +260,7 @@ Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 1535 -Last_Error Table definition on master and slave does not match: Column 1 type mismatch - received type 3, test.t5 has type 4 +Last_Error <Last_Error> Skip_Counter 0 Exec_Master_Log_Pos # Relay_Log_Space # @@ -274,9 +276,9 @@ Master_SSL_Key Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 -Last_IO_Error +Last_IO_Error <Last_IO_Error> Last_SQL_Errno 1535 -Last_SQL_Error Table definition on master and slave does not match: Column 1 type mismatch - received type 3, test.t5 has type 4 +Last_SQL_Error <Last_SQL_Error> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; INSERT INTO t9 VALUES (6); @@ -301,7 +303,7 @@ Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 1535 -Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 3, test.t6 has type 4 +Last_Error <Last_Error> Skip_Counter 0 Exec_Master_Log_Pos # Relay_Log_Space # @@ -317,9 +319,9 @@ Master_SSL_Key Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 -Last_IO_Error +Last_IO_Error <Last_IO_Error> Last_SQL_Errno 1535 -Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 3, test.t6 has type 4 +Last_SQL_Error <Last_SQL_Error> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; INSERT INTO t9 VALUES (6); @@ -343,7 +345,7 @@ Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 0 -Last_Error +Last_Error <Last_Error> Skip_Counter 0 Exec_Master_Log_Pos # Relay_Log_Space # @@ -359,9 +361,9 @@ Master_SSL_Key Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 -Last_IO_Error +Last_IO_Error <Last_IO_Error> Last_SQL_Errno 0 -Last_SQL_Error +Last_SQL_Error <Last_SQL_Error> INSERT INTO t7 VALUES (1),(2),(3); INSERT INTO t8 VALUES (1),(2),(3); SELECT * FROM t7 ORDER BY a; diff --git a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result index 12203379269..17b2a2f7b52 100644 --- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result +++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result @@ -37,6 +37,7 @@ ALTER TABLE t8 ADD e1 INT NOT NULL DEFAULT 0, ADD e2 INT NOT NULL DEFAULT 0, ADD e3 INT NOT NULL DEFAULT 0, ADD e4 INT NOT NULL DEFAULT 0, ADD e5 INT NOT NULL DEFAULT 0, ADD e6 INT NOT NULL DEFAULT 0, ADD e7 INT NOT NULL DEFAULT 0, ADD e8 INT NOT NULL DEFAULT 0; +set @@global.slave_exec_mode= 'IDEMPOTENT'; INSERT INTO t1_int VALUES (2, 4, 4711); INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar'); INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01'); @@ -60,6 +61,7 @@ a b 1 2 2 5 **** On Slave **** +set @@global.slave_exec_mode= default; SELECT a,b,x FROM t1_int ORDER BY a; a b x 1 2 42 @@ -123,7 +125,7 @@ Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 1364 -Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef. Field 'x' doesn't have a default value +Last_Error <Last_Error> Skip_Counter 0 Exec_Master_Log_Pos # Relay_Log_Space # @@ -139,9 +141,9 @@ Master_SSL_Key Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 -Last_IO_Error +Last_IO_Error <Last_IO_Error> Last_SQL_Errno 1364 -Last_SQL_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef. Field 'x' doesn't have a default value +Last_SQL_Error <Last_SQL_Error> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; INSERT INTO t9 VALUES (2); @@ -174,7 +176,7 @@ Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 0 -Last_Error +Last_Error <Last_Error> Skip_Counter 0 Exec_Master_Log_Pos # Relay_Log_Space # @@ -190,9 +192,9 @@ Master_SSL_Key Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 -Last_IO_Error +Last_IO_Error <Last_IO_Error> Last_SQL_Errno 0 -Last_SQL_Error +Last_SQL_Error <Last_SQL_Error> INSERT INTO t9 VALUES (4); INSERT INTO t4 VALUES (4); SHOW SLAVE STATUS; @@ -215,7 +217,7 @@ Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 1535 -Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 3, test.t4 has type 4 +Last_Error <Last_Error> Skip_Counter 0 Exec_Master_Log_Pos # Relay_Log_Space # @@ -231,9 +233,9 @@ Master_SSL_Key Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 -Last_IO_Error +Last_IO_Error <Last_IO_Error> Last_SQL_Errno 1535 -Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 3, test.t4 has type 4 +Last_SQL_Error <Last_SQL_Error> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; INSERT INTO t9 VALUES (5); @@ -258,7 +260,7 @@ Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 1535 -Last_Error Table definition on master and slave does not match: Column 1 type mismatch - received type 3, test.t5 has type 4 +Last_Error <Last_Error> Skip_Counter 0 Exec_Master_Log_Pos # Relay_Log_Space # @@ -274,9 +276,9 @@ Master_SSL_Key Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 -Last_IO_Error +Last_IO_Error <Last_IO_Error> Last_SQL_Errno 1535 -Last_SQL_Error Table definition on master and slave does not match: Column 1 type mismatch - received type 3, test.t5 has type 4 +Last_SQL_Error <Last_SQL_Error> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; INSERT INTO t9 VALUES (6); @@ -301,7 +303,7 @@ Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 1535 -Last_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 3, test.t6 has type 4 +Last_Error <Last_Error> Skip_Counter 0 Exec_Master_Log_Pos # Relay_Log_Space # @@ -317,9 +319,9 @@ Master_SSL_Key Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 -Last_IO_Error +Last_IO_Error <Last_IO_Error> Last_SQL_Errno 1535 -Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 3, test.t6 has type 4 +Last_SQL_Error <Last_SQL_Error> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; INSERT INTO t9 VALUES (6); @@ -343,7 +345,7 @@ Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 0 -Last_Error +Last_Error <Last_Error> Skip_Counter 0 Exec_Master_Log_Pos # Relay_Log_Space # @@ -359,9 +361,9 @@ Master_SSL_Key Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 -Last_IO_Error +Last_IO_Error <Last_IO_Error> Last_SQL_Errno 0 -Last_SQL_Error +Last_SQL_Error <Last_SQL_Error> INSERT INTO t7 VALUES (1),(2),(3); INSERT INTO t8 VALUES (1),(2),(3); SELECT * FROM t7 ORDER BY a; diff --git a/mysql-test/suite/rpl/r/rpl_row_trig001.result b/mysql-test/suite/rpl/r/rpl_row_trig001.result index 6665dc6d555..ea0ef27fccd 100644 --- a/mysql-test/suite/rpl/r/rpl_row_trig001.result +++ b/mysql-test/suite/rpl/r/rpl_row_trig001.result @@ -8,7 +8,7 @@ CREATE TABLE test.t1 (n MEDIUMINT NOT NULL, d DATETIME, PRIMARY KEY(n)); CREATE TABLE test.t2 (n MEDIUMINT NOT NULL AUTO_INCREMENT, f FLOAT, d DATETIME, PRIMARY KEY(n)); CREATE TABLE test.t3 (n MEDIUMINT NOT NULL AUTO_INCREMENT, d DATETIME, PRIMARY KEY(n)); INSERT INTO test.t1 VALUES (1,NOW()); -CREATE TRIGGER test.t2_ai AFTER INSERT ON test.t2 FOR EACH ROW UPDATE test.t1 SET d=NOW() where n = 1;// +CREATE TRIGGER test.t2_ai AFTER INSERT ON test.t2 FOR EACH ROW UPDATE test.t1 SET d=NOW() where n = 1// CREATE PROCEDURE test.p3() BEGIN INSERT INTO test.t3 (d) VALUES (NOW()); @@ -18,6 +18,7 @@ CREATE PROCEDURE test.p2() BEGIN INSERT INTO test.t2 (f,d) VALUES (RAND(),NOW()); END// +INSERT INTO test.t1 VALUES (1+1, NOW()); <End test section 2 (Tiggers & SP)> ----------------------------------- diff --git a/mysql-test/suite/rpl/r/rpl_server_id.result b/mysql-test/suite/rpl/r/rpl_server_id.result new file mode 100644 index 00000000000..1e74394c122 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_server_id.result @@ -0,0 +1,34 @@ +set global server_id=1; +reset master; +drop table if exists t1,t2,t3; +create table t1 (a int); +select @@server_id; +@@server_id +1 +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query 1 # use `test`; drop table if exists t1,t2,t3 +master-bin.000001 # Query 1 # use `test`; create table t1 (a int) +set global server_id=2; +create table t2 (b int); +select @@server_id; +@@server_id +2 +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query 1 # use `test`; drop table if exists t1,t2,t3 +master-bin.000001 # Query 1 # use `test`; create table t1 (a int) +master-bin.000001 # Query 2 # use `test`; create table t2 (b int) +set global server_id=3; +create table t3 (c int); +select @@server_id; +@@server_id +3 +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query 1 # use `test`; drop table if exists t1,t2,t3 +master-bin.000001 # Query 1 # use `test`; create table t1 (a int) +master-bin.000001 # Query 2 # use `test`; create table t2 (b int) +master-bin.000001 # Query 3 # use `test`; create table t3 (c int) +set global server_id=1; +drop table t1,t2,t3; diff --git a/mysql-test/suite/rpl/r/rpl_skip_error.result b/mysql-test/suite/rpl/r/rpl_skip_error.result index ed4c4a6b3bb..aacc89f7a47 100644 --- a/mysql-test/suite/rpl/r/rpl_skip_error.result +++ b/mysql-test/suite/rpl/r/rpl_skip_error.result @@ -29,7 +29,43 @@ select * from t1; a 1 2 -show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 851 # # master-bin.000001 Yes Yes 0 0 851 # None 0 No # No 0 0 +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table # +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno # +Last_IO_Error # +Last_SQL_Errno 0 +Last_SQL_Error drop table t1; diff --git a/mysql-test/suite/rpl/r/rpl_start_stop_slave.result b/mysql-test/suite/rpl/r/rpl_start_stop_slave.result index 1fcb586d1fb..04ece812f35 100644 --- a/mysql-test/suite/rpl/r/rpl_start_stop_slave.result +++ b/mysql-test/suite/rpl/r/rpl_start_stop_slave.result @@ -4,8 +4,8 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -stop slave; create table t1(n int); +stop slave; start slave; stop slave io_thread; start slave io_thread; diff --git a/mysql-test/suite/rpl/r/rpl_stm_charset.result b/mysql-test/suite/rpl/r/rpl_stm_charset.result index fd9c40843d5..1f21f226be8 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_charset.result +++ b/mysql-test/suite/rpl/r/rpl_stm_charset.result @@ -184,78 +184,101 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -drop database if exists mysqltest2/*!*/; +drop database if exists mysqltest2 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -drop database if exists mysqltest3/*!*/; +drop database if exists mysqltest3 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -create database mysqltest2 character set latin2/*!*/; +create database mysqltest2 character set latin2 +/*!*/; SET TIMESTAMP=1000000000/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=30/*!*/; -create database mysqltest3/*!*/; +create database mysqltest3 +/*!*/; SET TIMESTAMP=1000000000/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=64/*!*/; -drop database mysqltest3/*!*/; +drop database mysqltest3 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -create database mysqltest3/*!*/; +create database mysqltest3 +/*!*/; use mysqltest2/*!*/; SET TIMESTAMP=1000000000/*!*/; -create table t1 (a int auto_increment primary key, b varchar(100))/*!*/; +create table t1 (a int auto_increment primary key, b varchar(100)) +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1000000000/*!*/; /*!\C cp850 *//*!*/; SET @@session.character_set_client=4,@@session.collation_connection=27,@@session.collation_server=64/*!*/; -insert into t1 (b) values(@@character_set_server)/*!*/; +insert into t1 (b) values(@@character_set_server) +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1000000000/*!*/; -insert into t1 (b) values(@@collation_server)/*!*/; +insert into t1 (b) values(@@collation_server) +/*!*/; SET INSERT_ID=3/*!*/; SET TIMESTAMP=1000000000/*!*/; -insert into t1 (b) values(@@character_set_client)/*!*/; +insert into t1 (b) values(@@character_set_client) +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1000000000/*!*/; -insert into t1 (b) values(@@character_set_connection)/*!*/; +insert into t1 (b) values(@@character_set_connection) +/*!*/; SET INSERT_ID=5/*!*/; SET TIMESTAMP=1000000000/*!*/; -insert into t1 (b) values(@@collation_connection)/*!*/; +insert into t1 (b) values(@@collation_connection) +/*!*/; SET TIMESTAMP=1000000000/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=5,@@session.collation_server=64/*!*/; -truncate table t1/*!*/; +truncate table t1 +/*!*/; SET INSERT_ID=1/*!*/; SET TIMESTAMP=1000000000/*!*/; -insert into t1 (b) values(@@collation_connection)/*!*/; +insert into t1 (b) values(@@collation_connection) +/*!*/; SET INSERT_ID=2/*!*/; SET TIMESTAMP=1000000000/*!*/; -insert into t1 (b) values(LEAST("Müller","Muffler"))/*!*/; +insert into t1 (b) values(LEAST("Müller","Muffler")) +/*!*/; SET INSERT_ID=3/*!*/; SET TIMESTAMP=1000000000/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=31,@@session.collation_server=64/*!*/; -insert into t1 (b) values(@@collation_connection)/*!*/; +insert into t1 (b) values(@@collation_connection) +/*!*/; SET INSERT_ID=4/*!*/; SET TIMESTAMP=1000000000/*!*/; -insert into t1 (b) values(LEAST("Müller","Muffler"))/*!*/; +insert into t1 (b) values(LEAST("Müller","Muffler")) +/*!*/; SET TIMESTAMP=1000000000/*!*/; -truncate table t1/*!*/; +truncate table t1 +/*!*/; SET INSERT_ID=1/*!*/; SET @`a`:=_cp850 0x4DFC6C6C6572 COLLATE `cp850_general_ci`/*!*/; SET TIMESTAMP=1000000000/*!*/; -insert into t1 (b) values(collation(@a))/*!*/; +insert into t1 (b) values(collation(@a)) +/*!*/; SET TIMESTAMP=1000000000/*!*/; -drop database mysqltest2/*!*/; +drop database mysqltest2 +/*!*/; SET TIMESTAMP=1000000000/*!*/; -drop database mysqltest3/*!*/; +drop database mysqltest3 +/*!*/; use test/*!*/; SET TIMESTAMP=1000000000/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=30/*!*/; -CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))/*!*/; +CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255)) +/*!*/; SET TIMESTAMP=1000000000/*!*/; /*!\C koi8r *//*!*/; SET @@session.character_set_client=7,@@session.collation_connection=51,@@session.collation_server=30/*!*/; -INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ')/*!*/; +INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ') +/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; diff --git a/mysql-test/suite/rpl/r/rpl_stm_log.result b/mysql-test/suite/rpl/r/rpl_stm_log.result index 02f3dc9044a..18333f5e5e9 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_log.result +++ b/mysql-test/suite/rpl/r/rpl_stm_log.result @@ -196,8 +196,8 @@ master-bin.000001 # Intvar # # INSERT_ID=1 master-bin.000001 # Query # # use `test`; insert into t1 values (NULL) master-bin.000001 # Query # # use `test`; drop table t1 master-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM -master-bin.000001 # Begin_load_query # # ;file_id=1;block_len=581 -master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/words.dat' into table t1 ignore 1 lines ;file_id=1 +master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=581 +master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/words.dat' into table t1 ignore 1 lines ;file_id=# master-bin.000001 # Rotate # # master-bin.000002;pos=4 show binlog events in 'master-bin.000002'; Log_name Pos Event_type Server_id End_log_pos Info diff --git a/mysql-test/suite/rpl/r/rpl_stm_max_relay_size.result b/mysql-test/suite/rpl/r/rpl_stm_max_relay_size.result index 947b5686a18..2215b34814e 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_max_relay_size.result +++ b/mysql-test/suite/rpl/r/rpl_stm_max_relay_size.result @@ -28,7 +28,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 72960 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -43,7 +43,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 72960 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -76,7 +76,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 72960 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -91,7 +91,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 72960 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -124,7 +124,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 72960 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -139,7 +139,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 72960 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -169,7 +169,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File -Read_Master_Log_Pos 4 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File @@ -184,7 +184,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 0 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -215,7 +215,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 73046 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -230,7 +230,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 73046 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -259,7 +259,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 73122 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -274,7 +274,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 73122 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -293,10 +293,8 @@ Last_SQL_Errno 0 Last_SQL_Error flush logs; show master status; -File master-bin.000002 -Position 106 -Binlog_Do_DB <Binlog_Ignore_DB> -Binlog_Ignore_DB +File Position Binlog_Do_DB Binlog_Ignore_DB +master-bin.000002 # <Binlog_Do_DB> <Binlog_Ignore_DB> set global max_binlog_size= @my_max_binlog_size; # # End of 4.1 tests diff --git a/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result b/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result index d08e8646c73..bb89d150af7 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result +++ b/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result @@ -11,7 +11,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 106 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -26,7 +26,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 106 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -52,7 +52,7 @@ Master_User test Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 106 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -67,7 +67,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 106 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -92,7 +92,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File -Read_Master_Log_Pos 4 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File @@ -107,7 +107,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 0 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -132,7 +132,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 106 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -147,7 +147,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 106 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/suite/rpl/r/rpl_stm_until.result b/mysql-test/suite/rpl/r/rpl_stm_until.result index 947ce0153b1..619115aa534 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_until.result +++ b/mysql-test/suite/rpl/r/rpl_stm_until.result @@ -26,7 +26,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 784 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -41,7 +41,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 327 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition Master Until_Log_File master-bin.000001 @@ -72,7 +72,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 784 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -87,7 +87,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 327 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition Master Until_Log_File master-no-such-bin.000001 @@ -116,7 +116,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 784 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -131,7 +131,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 616 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition Relay Until_Log_File slave-relay-bin.000004 @@ -158,7 +158,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 784 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -173,7 +173,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 784 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition Master Until_Log_File master-bin.000001 diff --git a/mysql-test/suite/rpl/r/rpl_switch_stm_row_mixed.result b/mysql-test/suite/rpl/r/rpl_switch_stm_row_mixed.result index 75eb3b09c57..46e765ed228 100644 --- a/mysql-test/suite/rpl/r/rpl_switch_stm_row_mixed.result +++ b/mysql-test/suite/rpl/r/rpl_switch_stm_row_mixed.result @@ -471,21 +471,27 @@ master-bin.000001 # Query # # use `mysqltest1`; insert into t1 select 'emergency master-bin.000001 # Table_map # # table_id: # (mysqltest1.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # use `mysqltest1`; insert into t1 select "yesterday_24_" +master-bin.000001 # Query # # use `mysqltest1`; BEGIN master-bin.000001 # Query # # use `mysqltest1`; CREATE TABLE `t2` ( `rpad(UUID(),100,' ')` varchar(100) CHARACTER SET utf8 NOT NULL DEFAULT '' ) ENGINE=MyISAM master-bin.000001 # Table_map # # table_id: # (mysqltest1.t2) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `mysqltest1`; COMMIT +master-bin.000001 # Query # # use `mysqltest1`; BEGIN master-bin.000001 # Query # # use `mysqltest1`; CREATE TABLE `t3` ( `1` varbinary(108) NOT NULL DEFAULT '' ) master-bin.000001 # Table_map # # table_id: # (mysqltest1.t3) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `mysqltest1`; COMMIT +master-bin.000001 # Query # # use `mysqltest1`; BEGIN master-bin.000001 # Query # # use `mysqltest1`; CREATE TABLE `t4` ( `a` varchar(100) DEFAULT NULL ) master-bin.000001 # Table_map # # table_id: # (mysqltest1.t4) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `mysqltest1`; COMMIT master-bin.000001 # Query # # use `mysqltest1`; create table t5 select * from t1 where 3 in (select 1 union select 2 union select curdate() union select 3) master-bin.000001 # Table_map # # table_id: # (mysqltest1.t5) master-bin.000001 # Write_rows # # table_id: # @@ -799,21 +805,27 @@ master-bin.000001 # Query # # use `mysqltest1`; insert into t1 select 'emergency master-bin.000001 # Table_map # # table_id: # (mysqltest1.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # use `mysqltest1`; insert into t1 select "yesterday_24_" +master-bin.000001 # Query # # use `mysqltest1`; BEGIN master-bin.000001 # Query # # use `mysqltest1`; CREATE TABLE `t2` ( `rpad(UUID(),100,' ')` varchar(100) CHARACTER SET utf8 NOT NULL DEFAULT '' ) ENGINE=MyISAM master-bin.000001 # Table_map # # table_id: # (mysqltest1.t2) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `mysqltest1`; COMMIT +master-bin.000001 # Query # # use `mysqltest1`; BEGIN master-bin.000001 # Query # # use `mysqltest1`; CREATE TABLE `t3` ( `1` varbinary(108) NOT NULL DEFAULT '' ) master-bin.000001 # Table_map # # table_id: # (mysqltest1.t3) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `mysqltest1`; COMMIT +master-bin.000001 # Query # # use `mysqltest1`; BEGIN master-bin.000001 # Query # # use `mysqltest1`; CREATE TABLE `t4` ( `a` varchar(100) DEFAULT NULL ) master-bin.000001 # Table_map # # table_id: # (mysqltest1.t4) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `mysqltest1`; COMMIT master-bin.000001 # Query # # use `mysqltest1`; create table t5 select * from t1 where 3 in (select 1 union select 2 union select curdate() union select 3) master-bin.000001 # Table_map # # table_id: # (mysqltest1.t5) master-bin.000001 # Write_rows # # table_id: # diff --git a/mysql-test/suite/rpl/r/rpl_temporary_errors.result b/mysql-test/suite/rpl/r/rpl_temporary_errors.result index 5c681683b08..430e63c5859 100644 --- a/mysql-test/suite/rpl/r/rpl_temporary_errors.result +++ b/mysql-test/suite/rpl/r/rpl_temporary_errors.result @@ -12,6 +12,7 @@ INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4); SHOW STATUS LIKE 'Slave_retried_transactions'; Variable_name Value Slave_retried_transactions 0 +set @@global.slave_exec_mode= 'IDEMPOTENT'; UPDATE t1 SET a = 5, b = 47 WHERE a = 1; SELECT * FROM t1; a b @@ -28,6 +29,7 @@ a b 3 3 4 4 **** On Slave **** +set @@global.slave_exec_mode= default; SHOW STATUS LIKE 'Slave_retried_transactions'; Variable_name Value Slave_retried_transactions 0 @@ -44,7 +46,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 408 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -59,7 +61,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 408 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/suite/rpl/r/rpl_trigger.result b/mysql-test/suite/rpl/r/rpl_trigger.result index b4ce3ee1d36..68c82ed037f 100644 --- a/mysql-test/suite/rpl/r/rpl_trigger.result +++ b/mysql-test/suite/rpl/r/rpl_trigger.result @@ -91,21 +91,25 @@ select a=b && a=c from t1; a=b && a=c 1 SELECT routine_name, definer -FROM information_schema.routines; +FROM information_schema.routines +WHERE routine_name = 'bug12480'; routine_name definer bug12480 root@localhost SELECT trigger_name, definer -FROM information_schema.triggers; +FROM information_schema.triggers +WHERE trigger_name = 't1_first'; trigger_name definer t1_first root@localhost --- On slave -- SELECT routine_name, definer -FROM information_schema.routines; +FROM information_schema.routines +WHERE routine_name = 'bug12480'; routine_name definer bug12480 root@localhost SELECT trigger_name, definer -FROM information_schema.triggers; +FROM information_schema.triggers +WHERE trigger_name = 't1_first'; trigger_name definer t1_first root@localhost select a=b && a=c from t1; diff --git a/mysql-test/suite/rpl/r/rpl_truncate_3innodb.result b/mysql-test/suite/rpl/r/rpl_truncate_3innodb.result index a6580a5685b..728b8450314 100644 --- a/mysql-test/suite/rpl/r/rpl_truncate_3innodb.result +++ b/mysql-test/suite/rpl/r/rpl_truncate_3innodb.result @@ -38,8 +38,10 @@ show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1 master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2) master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; DROP TABLE t1 @@ -78,8 +80,10 @@ show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1 master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2) master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; DROP TABLE t1 @@ -118,9 +122,11 @@ show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1 master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; DROP TABLE t1 @@ -159,8 +165,10 @@ show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1 master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2) master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; DELETE FROM t1 master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; DROP TABLE t1 @@ -199,8 +207,10 @@ show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1 master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2) master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; DELETE FROM t1 master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; DROP TABLE t1 @@ -240,9 +250,11 @@ show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1 master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ diff --git a/mysql-test/suite/rpl/r/rpl_user.result b/mysql-test/suite/rpl/r/rpl_user.result new file mode 100644 index 00000000000..a98e7e9ca55 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_user.result @@ -0,0 +1,45 @@ +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; +set session sql_log_bin=0; +delete from mysql.user where Host='fakehost'; +set session sql_log_bin=1; +set session sql_log_bin=0; +delete from mysql.user where Host='fakehost'; +set session sql_log_bin=1; +create user 'foo'@'fakehost'; +create user 'foo'@'fakehost', 'bar'@'fakehost'; +ERROR HY000: Operation CREATE USER failed for 'foo'@'fakehost' +create user 'foo'@'fakehost', 'bar'@'fakehost'; +ERROR HY000: Operation CREATE USER failed for 'foo'@'fakehost','bar'@'fakehost' +select Host,User from mysql.user where Host='fakehost'; +Host User +fakehost bar +fakehost foo +rename user 'foo'@'fakehost' to 'foofoo'@'fakehost'; +rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'bar'@'fakehost' to 'barbar'@'fakehost'; +ERROR HY000: Operation RENAME USER failed for 'not_exist_user1'@'fakehost' +rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'not_exist_user2'@'fakehost' to 'barfoo'@'fakehost'; +ERROR HY000: Operation RENAME USER failed for 'not_exist_user1'@'fakehost','not_exist_user2'@'fakehost' +select Host,User from mysql.user where Host='fakehost'; +Host User +fakehost barbar +fakehost foofoo +drop user 'foofoo'@'fakehost'; +drop user 'not_exist_user1'@'fakehost', 'barbar'@'fakehost'; +ERROR HY000: Operation DROP USER failed for 'not_exist_user1'@'fakehost' +drop user 'not_exist_user1'@'fakehost', 'not_exist_user2'@'fakehost'; +ERROR HY000: Operation DROP USER failed for 'not_exist_user1'@'fakehost','not_exist_user2'@'fakehost' +select Host,User from mysql.user where Host='fakehost'; +Host User +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; create user 'foo'@'fakehost' +master-bin.000001 # Query # # use `test`; create user 'foo'@'fakehost', 'bar'@'fakehost' +master-bin.000001 # Query # # use `test`; rename user 'foo'@'fakehost' to 'foofoo'@'fakehost' +master-bin.000001 # Query # # use `test`; rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'bar'@'fakehost' to 'barbar'@'fakehost' +master-bin.000001 # Query # # use `test`; drop user 'foofoo'@'fakehost' +master-bin.000001 # Query # # use `test`; drop user 'not_exist_user1'@'fakehost', 'barbar'@'fakehost' diff --git a/mysql-test/suite/rpl/t/rpl_000015.test b/mysql-test/suite/rpl/t/rpl_000015.test index 80db596244b..45a43cd38d0 100644 --- a/mysql-test/suite/rpl/t/rpl_000015.test +++ b/mysql-test/suite/rpl/t/rpl_000015.test @@ -9,22 +9,22 @@ connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); connect (slave,localhost,root,,test,$SLAVE_MYPORT,$SLAVE_MYSOCK); connection master; reset master; -show master status; +source include/show_master_status.inc; save_master_pos; connection slave; reset slave; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; change master to master_host='127.0.0.1'; # The following needs to be cleaned up when change master is fixed -source include/show_slave_status.inc; +source include/show_slave_status2.inc; --replace_result $MASTER_MYPORT MASTER_PORT eval change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=$MASTER_MYPORT; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; start slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; connection master; --disable_warnings drop table if exists t1; diff --git a/mysql-test/suite/rpl/t/rpl_bug31076.test b/mysql-test/suite/rpl/t/rpl_bug31076.test index 1c7b0ca0fd1..9176bafe022 100644 --- a/mysql-test/suite/rpl/t/rpl_bug31076.test +++ b/mysql-test/suite/rpl/t/rpl_bug31076.test @@ -39,6 +39,24 @@ CREATE TABLE `visits_events` ( /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; --delimiter /*!*/; + +# at 4 (0x4) +#071204 14:29:31 server id 1 end_log_pos 106 +# Position Timestamp Type Master ID Size Master Pos Flags +# 4 3b 56 55 47 0f 01 00 00 00 66 00 00 00 6a 00 00 00 00 00 +# 17 04 00 35 2e 31 2e 32 33 2d 72 63 2d 64 65 62 75 |..5.1.23.rc.debu| +# 27 67 2d 6c 6f 67 00 00 00 00 00 00 00 00 00 00 00 |g.log...........| +# 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +# 47 00 00 00 00 3b 56 55 47 13 38 0d 00 08 00 12 00 |.....VUG.8......| +# 57 04 04 04 04 12 00 00 53 00 04 1a 08 00 00 00 08 |.......S........| +# 67 08 08 02 |...| +# Start: binlog v 4, server v 5.1.23-rc-debug-log created 071204 14:29:31 at startup + +BINLOG ' +O1ZVRw8BAAAAZgAAAGoAAAAAAAQANS4xLjIzLXJjLWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAA7VlVHEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC +'/*!*/; + # at 164170623 # at 164170679 #7918 3:59:2 server id 436 end_log_pos 164170679 diff --git a/mysql-test/suite/rpl/t/rpl_change_master.test b/mysql-test/suite/rpl/t/rpl_change_master.test index 7256fed656f..7e4800c5c77 100644 --- a/mysql-test/suite/rpl/t/rpl_change_master.test +++ b/mysql-test/suite/rpl/t/rpl_change_master.test @@ -18,13 +18,9 @@ save_master_pos; connection slave; --real_sleep 3 # wait for I/O thread to have read updates stop slave; ---replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 7 # 8 # 9 # 16 # 23 # 33 # 35 # 36 # -query_vertical SHOW SLAVE STATUS; +source include/show_slave_status2.inc; change master to master_user='root'; ---replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 7 # 8 # 9 # 16 # 23 # 33 # 35 # 36 # -query_vertical SHOW SLAVE STATUS; +source include/show_slave_status2.inc; start slave; sync_with_master; select * from t1; diff --git a/mysql-test/suite/rpl/t/rpl_colSize.test b/mysql-test/suite/rpl/t/rpl_colSize.test index 44fb878d4d2..c20f2c3fd35 100644 --- a/mysql-test/suite/rpl/t/rpl_colSize.test +++ b/mysql-test/suite/rpl/t/rpl_colSize.test @@ -147,12 +147,14 @@ INSERT INTO t1 VALUES ("This is a test of col a.", "This is a test of the large col c.", "Col d"); SELECT * FROM t1; +--replace_result default DEFAULT SHOW CREATE TABLE t1; sync_slave_with_master slave; --echo Insert some values and select them on slave SELECT * FROM t1; +--replace_result default DEFAULT SHOW CREATE TABLE t1; @@ -200,12 +202,14 @@ INSERT INTO t1 VALUES ( ); SELECT BIN(a), BIN(b), BIN(c), BIN(d), BIN(e) FROM t1; +--replace_result default DEFAULT SHOW CREATE TABLE t1; sync_slave_with_master slave; --echo Insert some values and select them on master SELECT BIN(a), BIN(b), BIN(c), BIN(d), BIN(e) FROM t1; +--replace_result default DEFAULT SHOW CREATE TABLE t1; --echo *** Cleanup *** diff --git a/mysql-test/suite/rpl/t/rpl_create_database.test b/mysql-test/suite/rpl/t/rpl_create_database.test index 70cff8daca2..e3e2e637594 100644 --- a/mysql-test/suite/rpl/t/rpl_create_database.test +++ b/mysql-test/suite/rpl/t/rpl_create_database.test @@ -42,9 +42,9 @@ USE mysqltest_sisyfos; # The following should *not* be replicated ALTER DATABASE mysqltest_bob CHARACTER SET latin1; -SHOW DATABASES; +SHOW DATABASES LIKE 'mysql%'; sync_slave_with_master; -SHOW DATABASES; +SHOW DATABASES LIKE 'mysql%'; connection master; DROP DATABASE IF EXISTS mysqltest_sisyfos; @@ -55,9 +55,9 @@ CREATE DATABASE mysqltest_sisyfos; USE mysqltest_sisyfos; CREATE TABLE t2 (a INT); let $VERSION=`select version()`; -SHOW DATABASES; +SHOW DATABASES LIKE 'mysql%'; sync_slave_with_master; -SHOW DATABASES; +SHOW DATABASES LIKE 'mysql%'; USE mysqltest_prometheus; SHOW TABLES; USE mysqltest_sisyfos; diff --git a/mysql-test/suite/rpl/t/rpl_critical_errors.test b/mysql-test/suite/rpl/t/rpl_critical_errors.test index abf827c8d1f..b35cd305f92 100644 --- a/mysql-test/suite/rpl/t/rpl_critical_errors.test +++ b/mysql-test/suite/rpl/t/rpl_critical_errors.test @@ -34,7 +34,8 @@ connection master1; # This sleep is picked so that the query above has started to insert # some rows into t2. If it hasn't the slave will not stop below. -sleep 4; +let $wait_condition= SELECT COUNT(*) > 1000 FROM t1; +source include/wait_condition.inc # SHOW PROCESSLIST; diff --git a/mysql-test/suite/rpl/t/rpl_drop_view.test b/mysql-test/suite/rpl/t/rpl_drop_view.test new file mode 100644 index 00000000000..8d826b8214d --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_drop_view.test @@ -0,0 +1,31 @@ +# test case for bug#30998 +# Drop View breaks replication if view does not exist +# + +source include/master-slave.inc; +--disable_warnings +drop table if exists t1, t2; +drop view if exists v1, v2, v3, not_exist_view; +--enable_warnings +create table t1 (a int); +create table t2 (b int); +create table t3 (c int); +create view v1 as select * from t1; +create view v2 as select * from t2; +create view v3 as select * from t3; +--error 1051 +drop view not_exist_view; +--error 1051 +drop view v1, not_exist_view; +--error 1146 +select * from v1; +drop view v2, v3; +save_master_pos; +connection slave; +sync_with_master; +--error 1146 +select * from v1; +--error 1146 +select * from v2; +--error 1146 +select * from v3; diff --git a/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test b/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test index 4e06a6a7096..e26e240b5ab 100644 --- a/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test +++ b/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test @@ -43,13 +43,14 @@ insert into t3 values(connection_id()); send update t2 set a = a + 1 + get_lock('crash_lock%20C', 10); connection master1; -real_sleep 2; +let $wait_condition= SELECT a > 1 FROM t2; +source include/wait_condition.inc; select (@id := id) - id from t3; kill @id; drop table t2,t3; insert into t4 values (3),(4); connection master; ---error 0,1053,2013 +--error 0,1053,2013,1048 reap; connection master1; save_master_pos; diff --git a/mysql-test/suite/rpl/t/rpl_grant.test b/mysql-test/suite/rpl/t/rpl_grant.test index 71e36342584..50b243eab92 100644 --- a/mysql-test/suite/rpl/t/rpl_grant.test +++ b/mysql-test/suite/rpl/t/rpl_grant.test @@ -9,12 +9,12 @@ connection master; CREATE USER dummy@localhost; CREATE USER dummy1@localhost, dummy2@localhost; -SELECT user, host FROM mysql.user WHERE user != 'root'; # root host non-determ -SELECT COUNT(*) FROM mysql.user; +SELECT user, host FROM mysql.user WHERE user like 'dummy%'; +SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%'; sync_slave_with_master; --echo **** On Slave **** -SELECT user,host FROM mysql.user WHERE user != 'root'; # root host non-determ -SELECT COUNT(*) FROM mysql.user; +SELECT user,host FROM mysql.user WHERE user like 'dummy%'; +SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%'; --echo **** On Master **** connection master; @@ -30,13 +30,11 @@ DROP USER nonexisting@localhost, dummy@localhost; # All users exist DROP USER dummy1@localhost, dummy2@localhost; -SELECT user, host FROM mysql.user WHERE user != 'root'; # root host non-determ -SELECT COUNT(*) FROM mysql.user; +SELECT user, host FROM mysql.user WHERE user like 'dummy%'; +SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%'; sync_slave_with_master; --echo **** On Slave **** -SELECT user,host FROM mysql.user WHERE user != 'root'; # root host non-determ -SELECT COUNT(*) FROM mysql.user; +SELECT user,host FROM mysql.user WHERE user like 'dummy%'; +SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%'; ---replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 8 # 9 # 23 # 33 # -query_vertical SHOW SLAVE STATUS; +source include/show_slave_status2.inc; diff --git a/mysql-test/suite/rpl/t/rpl_idempotency-master.opt b/mysql-test/suite/rpl/t/rpl_idempotency-master.opt new file mode 100644 index 00000000000..66f581b56d0 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_idempotency-master.opt @@ -0,0 +1,2 @@ +--innodb + diff --git a/mysql-test/suite/rpl/t/rpl_idempotency-slave.opt b/mysql-test/suite/rpl/t/rpl_idempotency-slave.opt new file mode 100644 index 00000000000..71ccf047474 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_idempotency-slave.opt @@ -0,0 +1,2 @@ +--slave-exec-mode=IDEMPOTENT --innodb + diff --git a/mysql-test/suite/rpl/t/rpl_idempotency.test b/mysql-test/suite/rpl/t/rpl_idempotency.test index 44956b7b459..cec91a6f4b7 100644 --- a/mysql-test/suite/rpl/t/rpl_idempotency.test +++ b/mysql-test/suite/rpl/t/rpl_idempotency.test @@ -2,6 +2,10 @@ # work the same way under statement based as under row based. source include/master-slave.inc; +connection master; +source include/have_innodb.inc; +connection slave; +source include/have_innodb.inc; connection master; CREATE TABLE t1 (a INT PRIMARY KEY); @@ -77,3 +81,335 @@ enable_query_log; connection master; DROP TABLE t1, t2; sync_slave_with_master; + +# bug#31609 Not all RBR slave errors reported as errors +# bug#31552 Replication breaks when deleting rows from out-of-sync table +# without PK + +# +# Idempotent applying is not default any longer. +# The default for slave-exec-mode option and server +# variable slave_exec_mode is 'STRICT'. +# When 'STRICT' mode is set, the slave SQL thread will stop whenever +# the row to change is not found. In 'IDEMPOTENT' mode, the SQL thread +# will continue running and apply the row - replace if it's Write_rows event - +# or skip to the next event. + +# the previous part of the tests was with IDEMPOTENT slave's mode. + + +# +# Other than above idempotent errors dealing with foreign keys constraint +# + +select @@global.slave_exec_mode /* must be IDEMPOTENT */; + +connection master; + +create table ti1 (b int primary key) engine = innodb; +create table ti2 (a int primary key, b int, foreign key (b) references ti1(b)) + engine = innodb; +set foreign_key_checks=1 /* ensure the check */; + +insert into ti1 values (1),(2),(3); +insert into ti2 set a=2, b=2; + +sync_slave_with_master; + +#connection slave; +select * from ti1 order by b /* must be (1),(2),(3) */; +insert into ti2 set a=1, b=1; +select * from ti2 order by b /* must be (1,1) (2,2) */; + +connection master; + +# from now on checking rbr specific idempotent errors +set @save_binlog_format= @@session.binlog_format; +set @@session.binlog_format= row; +delete from ti1 where b=1; + +select * from ti1 order by b /* must be (2),(3) */; + +# slave must catch up (expect some warnings in error.log) +sync_slave_with_master; + +#connection slave; +select * from ti1 order by b /* must stays as were on master (1),(2),(3) */; + +delete from ti1 where b=3; + +connection master; +insert into ti2 set a=3, b=3; + +# slave must catch up (expect some warnings in error.log) +sync_slave_with_master; + +#connection slave; +select * from ti2 order by b /* must be (1,1),(2,2) - not inserted */; + + +# +# Checking the new global sys variable +# + +connection slave; + +set global slave_exec_mode='IDEMPOTENT'; +set global slave_exec_mode='STRICT'; + +# checking mutual exclusion for the options +--error ER_SLAVE_AMBIGOUS_EXEC_MODE +set global slave_exec_mode='IDEMPOTENT,STRICT'; + +select @@global.slave_exec_mode /* must be STRICT */; + +# +# Checking stops. +# In the following sections strict slave sql thread is going to +# stop when faces an idempotent error. In order to proceed +# the mode is temporarily switched to indempotent. +# + +# +--echo *** foreign keys errors as above now forces to stop +# + +connection master; + +set foreign_key_checks=0; +drop table ti2, ti1; + +create table ti1 (b int primary key) engine = innodb; +create table ti2 (a int primary key, b int, foreign key (b) references ti1(b)) + engine = innodb; +set foreign_key_checks=1 /* ensure the check */; + +insert into ti1 values (1),(2),(3); +insert into ti2 set a=2, b=2; + +sync_slave_with_master; + +#connection slave; +select * from ti1 order by b /* must be (1),(2),(3) */; +--echo *** conspire future problem +insert into ti2 set a=1, b=1; +select * from ti2 order by b /* must be (1,1) (2,2) */; + +connection master; + +delete from ti1 where b=1 /* offending delete event */; +select * from ti1 order by b /* must be (2),(3) */; + +# foreign key: row is referenced + +--echo *** slave must stop +source include/wait_for_slave_sql_to_stop.inc; + +connection slave; + +let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); +disable_query_log; +eval SELECT "$last_error" AS Last_SQL_Error; +enable_query_log; + +select * from ti1 order by b /* must be (1),(2),(3) - not deleted */; +set foreign_key_checks= 0; +delete from ti2 where b=1; +set foreign_key_checks= 1; +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +connection master; +sync_slave_with_master; +#connection slave; +set global slave_exec_mode='STRICT'; + +connection master; + +sync_slave_with_master; + +#connection slave; +--echo *** conspire the following insert failure +# foreign key: no referenced row + +--echo *** conspire future problem +delete from ti1 where b=3; + +connection master; +insert into ti2 set a=3, b=3 /* offending write event */; +--echo *** slave must stop + +source include/wait_for_slave_sql_to_stop.inc; + +connection slave; + +let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); +disable_query_log; +eval SELECT "$last_error" AS Last_SQL_Error; +enable_query_log; + +select * from ti2 order by b /* must be (2,2) */; +set foreign_key_checks= 0; +insert into ti1 set b=3; +set foreign_key_checks= 1; +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +connection master; +sync_slave_with_master; +#connection slave; +set global slave_exec_mode='STRICT'; + +connection master; + +sync_slave_with_master; + +select * from ti2 order by b /* must be (2,2),(3,3) */; + +# +--echo *** other errors +# + +# dup key insert + +#connection slave; +--echo *** conspiring query +insert into ti1 set b=1; + +connection master; +insert into ti1 set b=1 /* offending write event */; + +--echo *** slave must stop +source include/wait_for_slave_sql_to_stop.inc; + +connection slave; + +let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); +disable_query_log; +eval SELECT "$last_error" AS Last_SQL_Error; +enable_query_log; + +set foreign_key_checks= 0; +delete from ti1 where b=1; +set foreign_key_checks= 1; +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +connection master; +sync_slave_with_master; +#connection slave; +set global slave_exec_mode='STRICT'; + +# key not found + +connection master; + +CREATE TABLE t1 (a INT PRIMARY KEY); +CREATE TABLE t2 (a INT); +INSERT INTO t1 VALUES (-1),(-2),(-3); +INSERT INTO t2 VALUES (-1),(-2),(-3); +sync_slave_with_master; + +#connection slave; +DELETE FROM t1 WHERE a = -2; +DELETE FROM t2 WHERE a = -2; +connection master; +DELETE FROM t1 WHERE a = -2; + +--echo *** slave must stop +source include/wait_for_slave_sql_to_stop.inc; + +connection slave; + +let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); +disable_query_log; +eval SELECT "$last_error" AS Last_SQL_Error; +enable_query_log; + +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +connection master; +sync_slave_with_master; +#connection slave; +set global slave_exec_mode='STRICT'; + +connection master; +DELETE FROM t2 WHERE a = -2; +--echo *** slave must stop +source include/wait_for_slave_sql_to_stop.inc; + +connection slave; + +let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); +disable_query_log; +eval SELECT "$last_error" AS Last_SQL_Error; +enable_query_log; + +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +connection master; +sync_slave_with_master; +#connection slave; +set global slave_exec_mode='STRICT'; + +UPDATE t1 SET a = 1 WHERE a = -1; +UPDATE t2 SET a = 1 WHERE a = -1; + +connection master; +UPDATE t1 SET a = 1 WHERE a = -1; + +--echo *** slave must stop +source include/wait_for_slave_sql_to_stop.inc; + +connection slave; + +let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); +disable_query_log; +eval SELECT "$last_error" AS Last_SQL_Error; +enable_query_log; + +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +connection master; +sync_slave_with_master; +#connection slave; +set global slave_exec_mode='STRICT'; + + +connection master; +UPDATE t2 SET a = 1 WHERE a = -1; + +--echo *** slave must stop +source include/wait_for_slave_sql_to_stop.inc; + +connection slave; + +let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); +disable_query_log; +eval SELECT "$last_error" AS Last_SQL_Error; +enable_query_log; + +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +connection master; +sync_slave_with_master; +#connection slave; +set global slave_exec_mode='STRICT'; + + +# cleanup for bug#31609 tests + +connection master; +set @@session.binlog_format= @save_binlog_format; +drop table t1,t2,ti2,ti1; + +sync_slave_with_master; + + +--echo *** end of tests + + + + + + + + + diff --git a/mysql-test/suite/rpl/t/rpl_ignore_table.test b/mysql-test/suite/rpl/t/rpl_ignore_table.test index fd4ae64165a..7f13b16b0de 100644 --- a/mysql-test/suite/rpl/t/rpl_ignore_table.test +++ b/mysql-test/suite/rpl/t/rpl_ignore_table.test @@ -119,6 +119,13 @@ show grants for mysqltest3@localhost; show grants for mysqltest4@localhost; # Cleanup +# connection slave; +# BUG31552 changes idempotency is not default any longer +# In order the following `delete from mysql.user', +# where mysqltest1 does not exist on slave, +# to succeed on slave the mode is temporarily changed +set global slave_exec_mode='IDEMPOTENT'; + connection master; drop table t1, t4, mysqltest2.t2; drop database mysqltest2; @@ -129,7 +136,10 @@ delete from mysql.db where user like "mysqltest%"; # move it to slave instead #delete from mysql.tables_priv where user like "mysqltest%"; delete from mysql.columns_priv where user like "mysqltest%"; + sync_slave_with_master; +# bug#31552: do not restore the mode here but later in order +# to succeed with yet the following delete from mysql.tables_priv #BUG27606 delete from mysql.tables_priv where user like "mysqltest%"; @@ -155,6 +165,7 @@ CREATE TEMPORARY TABLE tmptbl504451f4258$1 (id INT NOT NULL) ENGINE=MEMORY; INSERT INTO t5 (word) VALUES ('TEST’'); SELECT HEX(word) FROM t5; sync_slave_with_master; +set @@global.slave_exec_mode= default; # bug#31552 comments above connection slave; SELECT HEX(word) FROM t5; --error 1146 diff --git a/mysql-test/suite/rpl/t/rpl_init_slave.test b/mysql-test/suite/rpl/t/rpl_init_slave.test index 139b4902e12..1511bd541ed 100644 --- a/mysql-test/suite/rpl/t/rpl_init_slave.test +++ b/mysql-test/suite/rpl/t/rpl_init_slave.test @@ -4,9 +4,17 @@ source include/master-slave.inc; # Test of init_slave variable # +set global max_connections=151; + +connection slave; +stop slave; +source include/wait_for_slave_to_stop.inc; +start slave; +source include/wait_for_slave_to_start.inc; + +connection master; save_master_pos; connection slave; -sleep 1; show variables like 'init_slave'; show variables like 'max_connections'; sync_with_master; diff --git a/mysql-test/suite/rpl/t/rpl_insert.test b/mysql-test/suite/rpl/t/rpl_insert.test index 77847dd24f2..c5c82517797 100644 --- a/mysql-test/suite/rpl/t/rpl_insert.test +++ b/mysql-test/suite/rpl/t/rpl_insert.test @@ -17,18 +17,8 @@ let $query = "INSERT DELAYED INTO t1 VALUES (1, 'Dr. No'), (2, 'From Russia With --exec $MYSQL_SLAP --silent --concurrency=5 --iterations=200 --query=$query --delimiter=";" # Wait until all the 5000 inserts has been inserted into the table ---disable_query_log -let $counter= 300; # Max 30 seconds wait -while (`select count(*)!=5000 from mysqlslap.t1`) -{ - sleep 0.1; - dec $counter; - if (!$counter) - { - Number of records in t1 didnt reach 5000; - } -} ---enable_query_log +let $wait_condition= SELECT COUNT(*) = 5000 FROM mysqlslap.t1; +--source include/wait_condition.inc SELECT COUNT(*) FROM mysqlslap.t1; sync_slave_with_master; diff --git a/mysql-test/suite/rpl/t/rpl_invoked_features.test b/mysql-test/suite/rpl/t/rpl_invoked_features.test index ab996840e97..17cdc1e61cf 100644 --- a/mysql-test/suite/rpl/t/rpl_invoked_features.test +++ b/mysql-test/suite/rpl/t/rpl_invoked_features.test @@ -202,10 +202,10 @@ SET GLOBAL EVENT_SCHEDULER = off; # Check original objects --echo SHOW TABLES LIKE 't%'; -SELECT table_name FROM information_schema.views WHERE table_schema='test' order by table_name; -SELECT trigger_name, event_manipulation, event_object_table FROM information_schema.triggers WHERE trigger_schema='test' order by trigger_name; -SELECT routine_type, routine_name FROM information_schema.routines WHERE routine_schema='test' order by routine_name; -SELECT event_name, status FROM information_schema.events WHERE event_schema='test' order by event_name; +SELECT table_name FROM information_schema.views WHERE table_schema='test' ORDER BY table_name; +SELECT trigger_name, event_manipulation, event_object_table FROM information_schema.triggers WHERE trigger_schema='test' ORDER BY trigger_name; +SELECT routine_type, routine_name FROM information_schema.routines WHERE routine_schema='test' ORDER BY routine_name; +SELECT event_name, status FROM information_schema.events WHERE event_schema='test' ORDER BY event_name; # Check original data --echo @@ -229,10 +229,10 @@ SELECT a,b FROM v11 ORDER BY a; # Check replicated objects --echo SHOW TABLES LIKE 't%'; -SELECT table_name FROM information_schema.views WHERE table_schema='test' order by table_name; -SELECT trigger_name, event_manipulation, event_object_table FROM information_schema.triggers WHERE trigger_schema='test' order by trigger_name; -SELECT routine_type, routine_name FROM information_schema.routines WHERE routine_schema='test' order by routine_name; -SELECT event_name, status FROM information_schema.events WHERE event_schema='test' order by event_name; +SELECT table_name FROM information_schema.views WHERE table_schema='test' ORDER BY table_name; +SELECT trigger_name, event_manipulation, event_object_table FROM information_schema.triggers WHERE trigger_schema='test' ORDER BY trigger_name; +SELECT routine_type, routine_name FROM information_schema.routines WHERE routine_schema='test' ORDER BY routine_name; +SELECT event_name, status FROM information_schema.events WHERE event_schema='test' ORDER BY event_name; # Check replicated data --echo diff --git a/mysql-test/suite/rpl/t/rpl_load_from_master.test b/mysql-test/suite/rpl/t/rpl_load_from_master.test index 9bab7d5696e..b04d8a44226 100644 --- a/mysql-test/suite/rpl/t/rpl_load_from_master.test +++ b/mysql-test/suite/rpl/t/rpl_load_from_master.test @@ -54,7 +54,7 @@ connection master; set sql_log_bin = 0; create database mysqltest2; create database mysqltest; -show databases; +show databases like 'mysql%'; create table mysqltest2.t1(n int, s char(20))ENGINE=MyISAM; create table mysqltest2.t2(n int, s text)ENGINE=MyISAM; insert into mysqltest2.t1 values (1, 'one'), (2, 'two'), (3, 'three'); @@ -71,7 +71,7 @@ connection slave; sync_with_master; # This should show that the slave is empty at this point -show databases; +show databases like 'mysql%'; # Create mysqltest2 and mysqltest3 on slave; we expect that LOAD DATA FROM # MASTER will neither touch database mysqltest nor mysqltest3 create database mysqltest2; @@ -95,7 +95,7 @@ insert into mysqltest.t3 values (1, 'original bar.t3'); load data from master; # Now let's check if we have the right tables and the right data in them -show databases; +show databases like 'mysql%'; use mysqltest2; # LOAD DATA FROM MASTER uses only replicate_*_db rules to decide which diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_map-master.opt b/mysql-test/suite/rpl/t/rpl_loaddata_map-master.opt new file mode 100644 index 00000000000..831680eb5ef --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_map-master.opt @@ -0,0 +1 @@ +--read_buffer_size=12K --max_allowed_packet=8K diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_map-slave.opt b/mysql-test/suite/rpl/t/rpl_loaddata_map-slave.opt new file mode 100644 index 00000000000..95f55bcf7d8 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_map-slave.opt @@ -0,0 +1 @@ +--max_allowed_packet=8K diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_map.test b/mysql-test/suite/rpl/t/rpl_loaddata_map.test new file mode 100644 index 00000000000..3d6f09844b6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_map.test @@ -0,0 +1,53 @@ +# +# check replication of load data with the server parameters subjected to +# read_buffer_size > max_allowed_packet +# +# BUG#30435 loading large LOAD DATA INFILE breaks slave with +# read_buffer_size set on master +# BUG#33413 show binlog events fails if binlog has event size of close +# to max_allowed_packet + +source include/master-slave.inc; +source include/have_innodb.inc; +source include/have_binlog_format_mixed_or_statement.inc; + +--disable_query_log +let $rows= 5000; +create table t1 (id int not null primary key auto_increment); + +while($rows) +{ + eval insert into t1 values (null); + dec $rows; +} +eval select * into outfile '$MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' from t1; +flush logs; +--enable_query_log + +connection master; +create table t2 (id int not null primary key auto_increment); + +select @@session.read_buffer_size - @@session.max_allowed_packet > 0 ; + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval load data infile '$MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2; +select count(*) from t2 /* 5 000 */; + +# the binglog will show fragmented Append_block events +--let $binlog_start=106 +--replace_column 5 # +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /file_id=[0-9]+/file_id=#/ +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--eval show binlog events in 'master-bin.000002' from $binlog_start + + +sync_slave_with_master; +#connection slave; +select count(*) from t2 /* 5 000 */; + +connection master; +drop table t1, t2; +sync_slave_with_master; +remove_file $MYSQLTEST_VARDIR/tmp/bug30435_5k.txt; + +--echo end of the tests diff --git a/mysql-test/suite/rpl/t/rpl_loadfile.test b/mysql-test/suite/rpl/t/rpl_loadfile.test index a671bab15bb..532db77c248 100644 --- a/mysql-test/suite/rpl/t/rpl_loadfile.test +++ b/mysql-test/suite/rpl/t/rpl_loadfile.test @@ -36,11 +36,12 @@ delimiter ;| CALL test.p1(); SELECT * FROM test.t1 ORDER BY blob_column; save_master_pos; -# Need to allow some time when NDB engine is used for -# the injector thread to have time to populate binlog -sleep 10; sync_slave_with_master; connection slave; +# Need to allow some time when NDB engine is used for +# the injector thread to have time to populate binlog +let $wait_condition= SELECT INSTR(blob_column,'aberration') > 0 FROM test.t1 WHERE a = 2; +--source include/wait_condition.inc SELECT * FROM test.t1 ORDER BY blob_column; # Cleanup diff --git a/mysql-test/suite/rpl/t/rpl_log_pos.test b/mysql-test/suite/rpl/t/rpl_log_pos.test index e5ad6f39ed2..45a097b6f14 100644 --- a/mysql-test/suite/rpl/t/rpl_log_pos.test +++ b/mysql-test/suite/rpl/t/rpl_log_pos.test @@ -11,14 +11,13 @@ # Passes with rbr no problem, removed statement include [jbm] source include/master-slave.inc; ---replace_column 3 <Binlog_Ignore_DB> -show master status; +source include/show_master_status.inc; sync_slave_with_master; stop slave; --source include/wait_for_slave_to_stop.inc change master to master_log_pos=75; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; start slave; let $slave_param= Slave_SQL_Running; let $slave_param_value= Yes; @@ -31,15 +30,14 @@ stop slave; source include/show_slave_status.inc; connection master; ---replace_column 3 <Binlog_Ignore_DB> -show master status; +source include/show_master_status.inc; create table if not exists t1 (n int); drop table if exists t1; create table t1 (n int); insert into t1 values (1),(2),(3); save_master_pos; connection slave; -change master to master_log_pos=106; +change master to master_log_pos=4; start slave; sync_with_master; select * from t1 ORDER BY n; diff --git a/mysql-test/suite/rpl/t/rpl_misc_functions.test b/mysql-test/suite/rpl/t/rpl_misc_functions.test index 1c94471c975..4a47e9645f9 100644 --- a/mysql-test/suite/rpl/t/rpl_misc_functions.test +++ b/mysql-test/suite/rpl/t/rpl_misc_functions.test @@ -109,6 +109,7 @@ DROP TABLE t1, t1_slave; DROP PROCEDURE test_replication_sp1; DROP PROCEDURE test_replication_sp2; DROP FUNCTION test_replication_sf; +--remove_file $MYSQLTEST_VARDIR/master-data/test/rpl_misc_functions.outfile --sync_slave_with_master diff --git a/mysql-test/suite/rpl/t/rpl_rotate_logs.test b/mysql-test/suite/rpl/t/rpl_rotate_logs.test index 998bce33e8f..9133c429934 100644 --- a/mysql-test/suite/rpl/t/rpl_rotate_logs.test +++ b/mysql-test/suite/rpl/t/rpl_rotate_logs.test @@ -65,14 +65,14 @@ insert into temp_table values ("testing temporary tables"); create table t1 (s text); insert into t1 values('Could not break slave'),('Tried hard'); sync_slave_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; select * from t1; connection master; flush logs; create table t2(m int not null auto_increment primary key); insert into t2 values (34),(67),(123); flush logs; -show binary logs; +source include/show_binary_logs.inc; create table t3 select * from temp_table; sync_slave_with_master; @@ -106,10 +106,10 @@ connection master; sync_slave_with_master; connection master; purge master logs to 'master-bin.000002'; -show master logs; +source include/show_master_logs.inc; # we just tests if synonyms are accepted purge binary logs to 'master-bin.000002'; -show binary logs; +source include/show_binary_logs.inc; # Calculate time to use in "purge master logs before" by taking # last modification time of t2 and adding 1 second @@ -122,10 +122,10 @@ select @time_for_purge:=DATE_ADD(UPDATE_TIME, INTERVAL 1 SECOND) --enable_result_log purge master logs before (@time_for_purge); -show binary logs; +source include/show_binary_logs.inc; insert into t2 values (65); sync_slave_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; select * from t2; # @@ -148,14 +148,14 @@ while ($1) enable_query_log; select count(*) from t3 where n >= 4; create table t4 select * from temp_table; -show binary logs; -show master status; +source include/show_binary_logs.inc; +source include/show_master_status.inc; save_master_pos; connection slave; sync_with_master; select * from t4; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; # because of concurrent insert, the table may not be up to date # if we do not lock lock tables t3 read; diff --git a/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test b/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test index 07fe763eb3c..5904585a050 100644 --- a/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test +++ b/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test @@ -242,12 +242,17 @@ INSERT INTO t1 VALUES (1,'master,slave'), (2,'master,slave'); sync_slave_with_master; UPDATE t1 SET a = 5, b = 'slave' WHERE a = 1; SELECT * FROM t1 ORDER BY a; +# since bug#31552/31609 idempotency is not default any longer. In +# order the preceeding test UPDATE t1 to pass the mode is switched +# temprorarily +set @@global.slave_exec_mode= 'IDEMPOTENT'; --echo **** On Master **** connection master; UPDATE t1 SET a = 5, b = 'master' WHERE a = 1; SELECT * FROM t1 ORDER BY a; --echo **** On Slave **** sync_slave_with_master; +set @@global.slave_exec_mode= default; let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1); disable_query_log; eval SELECT "$last_error" AS Last_SQL_Error; diff --git a/mysql-test/suite/rpl/t/rpl_row_create_table.test b/mysql-test/suite/rpl/t/rpl_row_create_table.test index 32a6299f28b..ffddfd2ce4a 100644 --- a/mysql-test/suite/rpl/t/rpl_row_create_table.test +++ b/mysql-test/suite/rpl/t/rpl_row_create_table.test @@ -72,7 +72,7 @@ CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3; # Shouldn't be written to the binary log --replace_column 1 # 4 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 1100; +SHOW BINLOG EVENTS FROM 1374; # Test that INSERT-SELECT works the same way as for SBR. CREATE TABLE t7 (a INT, b INT UNIQUE); @@ -82,7 +82,7 @@ SELECT * FROM t7 ORDER BY a,b; # Should be written to the binary log --replace_column 1 # 4 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 1100; +SHOW BINLOG EVENTS FROM 1374; sync_slave_with_master; SELECT * FROM t7 ORDER BY a,b; @@ -94,7 +94,7 @@ INSERT INTO t7 SELECT a,b FROM tt4; ROLLBACK; --replace_column 1 # 4 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 1298; +SHOW BINLOG EVENTS FROM 1572; SELECT * FROM t7 ORDER BY a,b; sync_slave_with_master; SELECT * FROM t7 ORDER BY a,b; @@ -110,7 +110,7 @@ CREATE TEMPORARY TABLE tt7 SELECT 1; --query_vertical SHOW CREATE TABLE t9 --replace_column 1 # 4 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 1396; +SHOW BINLOG EVENTS FROM 1670; sync_slave_with_master; --echo **** On Slave **** --query_vertical SHOW CREATE TABLE t8 diff --git a/mysql-test/suite/rpl/t/rpl_row_mystery22.test b/mysql-test/suite/rpl/t/rpl_row_mystery22.test index 9933fec22fc..a3ba8648b22 100644 --- a/mysql-test/suite/rpl/t/rpl_row_mystery22.test +++ b/mysql-test/suite/rpl/t/rpl_row_mystery22.test @@ -9,6 +9,12 @@ # first, cause a duplicate key problem on the slave create table t1(n int auto_increment primary key, s char(10)); sync_slave_with_master; + +# bug#31552/31609 idempotency is not default any longer +# so that the declared in heading comments aim of the test +# should be backed up with explicit setting of the slave mode +set @@global.slave_exec_mode= 'IDEMPOTENT'; + insert into t1 values (2,'old'); connection master; insert into t1 values(NULL,'new'); @@ -43,3 +49,4 @@ select * from t1 order by n; connection master; drop table t1; sync_slave_with_master; +set @@global.slave_exec_mode= default; diff --git a/mysql-test/suite/rpl/t/rpl_row_sp001.test b/mysql-test/suite/rpl/t/rpl_row_sp001.test index c12e73b6861..1595c4a21d5 100644 --- a/mysql-test/suite/rpl/t/rpl_row_sp001.test +++ b/mysql-test/suite/rpl/t/rpl_row_sp001.test @@ -46,11 +46,15 @@ delimiter ;// -- disable_query_log -- disable_result_log +SET @wait_count=1; let $1=10; while ($1) { call test.p1(); - sleep 1; + let $wait_condition= SELECT COUNT(*) = @wait_count FROM test.t1; + -- source include/wait_condition.inc + -- disable_query_log + SET @wait_count = @wait_count + 1; dec $1; } -- enable_result_log diff --git a/mysql-test/suite/rpl/t/rpl_row_sp005.test b/mysql-test/suite/rpl/t/rpl_row_sp005.test index 054fa02f514..b118242dc3b 100644 --- a/mysql-test/suite/rpl/t/rpl_row_sp005.test +++ b/mysql-test/suite/rpl/t/rpl_row_sp005.test @@ -84,12 +84,15 @@ let $message=< ---- Master selects-- >; --source include/show_msg.inc connection master; CALL test.p1(); -sleep 6; +let $wait_condition= SELECT COUNT(*) = 4 FROM t3; +--source include/wait_condition.inc +save_master_pos; SELECT * FROM test.t3 ORDER BY id3; let $message=< ---- Slave selects-- >; --source include/show_msg.inc connection slave; +sync_with_master; SELECT * FROM test.t3 ORDER BY id3; connection master; diff --git a/mysql-test/suite/rpl/t/rpl_row_stop_middle.test b/mysql-test/suite/rpl/t/rpl_row_stop_middle.test index da363736100..bc169bebfcd 100644 --- a/mysql-test/suite/rpl/t/rpl_row_stop_middle.test +++ b/mysql-test/suite/rpl/t/rpl_row_stop_middle.test @@ -33,7 +33,8 @@ start slave; # hope one second is not enough for slave to reach the last # Rows_log_event, so that test actually tests something. -real_sleep 1; +let $wait_condition= SELECT COUNT(*) >= 10 FROM t1; +--source include/wait_condition.inc stop slave; # see if slave hangs on DROP TABLE diff --git a/mysql-test/suite/rpl/t/rpl_row_trig001.test b/mysql-test/suite/rpl/t/rpl_row_trig001.test index 7b1fca2d6a1..8669034713a 100644 --- a/mysql-test/suite/rpl/t/rpl_row_trig001.test +++ b/mysql-test/suite/rpl/t/rpl_row_trig001.test @@ -39,7 +39,7 @@ CREATE TABLE test.t3 (n MEDIUMINT NOT NULL AUTO_INCREMENT, d DATETIME, PRIMARY K INSERT INTO test.t1 VALUES (1,NOW()); delimiter //; -CREATE TRIGGER test.t2_ai AFTER INSERT ON test.t2 FOR EACH ROW UPDATE test.t1 SET d=NOW() where n = 1;// +CREATE TRIGGER test.t2_ai AFTER INSERT ON test.t2 FOR EACH ROW UPDATE test.t1 SET d=NOW() where n = 1// CREATE PROCEDURE test.p3() BEGIN INSERT INTO test.t3 (d) VALUES (NOW()); @@ -51,18 +51,33 @@ BEGIN END// delimiter ;// +# Make sure that all definition have propagated to the slave +sync_slave_with_master; + +connection master; -- disable_query_log -- disable_result_log +SET @wait_count = 1; let $1=10; while ($1) { CALL test.p2(); - sleep 1; + let $wait_condition= SELECT COUNT(*) = @wait_count FROM test.t3; + --source include/wait_condition.inc + --disable_query_log + SET @wait_count = @wait_count + 1; dec $1; } -- enable_result_log -- enable_query_log +# Just a precaution to make sure all changes have made it over to the +# slave +connection master; +let $count = `select count(*) from t1`; +eval INSERT INTO test.t1 VALUES ($count+1, NOW()); +sync_slave_with_master; + #show binlog events; #select * from test.t2; #select * from test.t3; diff --git a/mysql-test/suite/rpl/t/rpl_row_trig003.test b/mysql-test/suite/rpl/t/rpl_row_trig003.test index 4a1bbc5ca89..5d667e29d69 100644 --- a/mysql-test/suite/rpl/t/rpl_row_trig003.test +++ b/mysql-test/suite/rpl/t/rpl_row_trig003.test @@ -108,11 +108,13 @@ UPDATE test.t2 SET b1 = 0 WHERE b1 = 1; INSERT INTO test.t1 VALUES(NULL,1,'add some more test data test.', 'and hope for the best', 3.321,5.221,0,YEAR(NOW()),NOW()); -# To make sure BUG#14698 is gone, we sleep 2 seconds before calling trigger +# To make sure BUG#14698 is gone, we sleep before calling trigger # (with the bug in, that caused differences in TIMESTAMP columns). # We just need to let the machine's clock advance, it's not -# to do synchronization, so real_sleep is good. -real_sleep 2; +# to do synchronization. + +let $wait_condition= SELECT SUM(f)= ROUND(SUM(f)) FROM t3; +--source include/wait_condition.inc DELETE FROM test.t1 WHERE id = 1; diff --git a/mysql-test/suite/rpl/t/rpl_server_id.test b/mysql-test/suite/rpl/t/rpl_server_id.test new file mode 100644 index 00000000000..6e98ec6ee6d --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_server_id.test @@ -0,0 +1,29 @@ +# Test for BUG#28908 Replication: set global server_id is not setting the session server_id + +-- source include/have_log_bin.inc + +let $saved_server_id=`select @@server_id`; +set global server_id=1; +reset master; + +-- disable_warnings +drop table if exists t1,t2,t3; +-- enable_warnings + +create table t1 (a int); +select @@server_id; +source include/show_binlog_events2.inc; + +set global server_id=2; +create table t2 (b int); +select @@server_id; +source include/show_binlog_events2.inc; + +set global server_id=3; +create table t3 (c int); +select @@server_id; +source include/show_binlog_events2.inc; + +# cleanup +eval set global server_id=$saved_server_id; +drop table t1,t2,t3; diff --git a/mysql-test/suite/rpl/t/rpl_session_var.test b/mysql-test/suite/rpl/t/rpl_session_var.test index 2491611e23d..50efc8930a1 100644 --- a/mysql-test/suite/rpl/t/rpl_session_var.test +++ b/mysql-test/suite/rpl/t/rpl_session_var.test @@ -51,8 +51,9 @@ CREATE TABLE t1 ( `data` varchar(100), PRIMARY KEY (`id`) ) ENGINE=MyISAM; - +--disable_warnings INSERT INTO t1(data) VALUES(SESSION_USER()); +--enable_warnings save_master_pos; connection slave; sync_with_master; diff --git a/mysql-test/suite/rpl/t/rpl_skip_error.test b/mysql-test/suite/rpl/t/rpl_skip_error.test index 72d434d9c9b..efd46f4fa09 100644 --- a/mysql-test/suite/rpl/t/rpl_skip_error.test +++ b/mysql-test/suite/rpl/t/rpl_skip_error.test @@ -50,9 +50,7 @@ sync_slave_with_master; connection slave; select @@server_id; select * from t1; ---replace_column 1 # 8 # 9 # 23 # 33 # ---replace_result $MASTER_MYPORT MASTER_PORT -show slave status; +source include/show_slave_status2.inc; connection master; drop table t1; sync_with_master; diff --git a/mysql-test/suite/rpl/t/rpl_sp.test b/mysql-test/suite/rpl/t/rpl_sp.test index f363b64558a..87503dbf9a3 100644 --- a/mysql-test/suite/rpl/t/rpl_sp.test +++ b/mysql-test/suite/rpl/t/rpl_sp.test @@ -561,7 +561,6 @@ set @a:= mysqltest2.f1(); sync_slave_with_master; connection master; - # Final inspection which verifies how all statements of this test file # were written to the binary log. --replace_column 2 # 5 # @@ -579,7 +578,7 @@ set global log_bin_trust_function_creators=0; # Clean up drop database mysqltest; drop database mysqltest2; +sync_slave_with_master; --echo End of 5.0 tests --echo End of 5.1 tests - diff --git a/mysql-test/suite/rpl/t/rpl_ssl1.test b/mysql-test/suite/rpl/t/rpl_ssl1.test index b660c3991dd..b5355d737d5 100644 --- a/mysql-test/suite/rpl/t/rpl_ssl1.test +++ b/mysql-test/suite/rpl/t/rpl_ssl1.test @@ -24,7 +24,8 @@ start slave; connection master; insert into t1 values (1); #reasonable timeout for changes to propagate to slave -sleep 3; +let $wait_condition= SELECT COUNT(*) = 1 FROM t1; +source include/wait_condition.inc; connection slave; select * from t1; diff --git a/mysql-test/suite/rpl/t/rpl_start_stop_slave.test b/mysql-test/suite/rpl/t/rpl_start_stop_slave.test index 19988cf902a..93c613f4cf4 100644 --- a/mysql-test/suite/rpl/t/rpl_start_stop_slave.test +++ b/mysql-test/suite/rpl/t/rpl_start_stop_slave.test @@ -3,12 +3,12 @@ source include/master-slave.inc; # # Bug#6148 () # -connection slave; -stop slave; - # Let the master do lots of insertions connection master; create table t1(n int); +sync_slave_with_master; +stop slave; +connection master; let $1=5000; disable_query_log; while ($1) @@ -21,7 +21,8 @@ save_master_pos; connection slave; start slave; -sleep 1; +let $wait_condition= SELECT COUNT(*) > 0 FROM t1; +source include/wait_condition.inc; stop slave io_thread; start slave io_thread; sync_with_master; diff --git a/mysql-test/suite/rpl/t/rpl_stm_until.test b/mysql-test/suite/rpl/t/rpl_stm_until.test index c8d3cb1823d..2793e8833fd 100644 --- a/mysql-test/suite/rpl/t/rpl_stm_until.test +++ b/mysql-test/suite/rpl/t/rpl_stm_until.test @@ -31,20 +31,20 @@ start slave until master_log_file='master-bin.000001', master_log_pos=323; --source include/wait_for_slave_sql_to_stop.inc # here table should be still not deleted select * from t1; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; # this should fail right after start start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; --source include/wait_for_slave_sql_to_stop.inc # again this table should be still not deleted select * from t1; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; # try replicate all up to and not including the second insert to t2; start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=746; --source include/wait_for_slave_sql_to_stop.inc select * from t2; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; # clean up start slave; @@ -61,7 +61,7 @@ start slave until master_log_file='master-bin.000001', master_log_pos=776; --source include/wait_for_slave_sql_to_stop.inc # here the sql slave thread should be stopped --replace_result bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004 -source include/show_slave_status.inc; +source include/show_slave_status2.inc; #testing various error conditions --error 1277 diff --git a/mysql-test/suite/rpl/t/rpl_switch_stm_row_mixed.test b/mysql-test/suite/rpl/t/rpl_switch_stm_row_mixed.test index 67dbde5e89d..7d20a559e0a 100644 --- a/mysql-test/suite/rpl/t/rpl_switch_stm_row_mixed.test +++ b/mysql-test/suite/rpl/t/rpl_switch_stm_row_mixed.test @@ -293,7 +293,8 @@ insert delayed into t2 values(rand()); set @a=2.345; insert delayed into t2 values(@a); -sleep 4; # time for the delayed inserts to reach disk +let $wait_condition= SELECT COUNT(*) = 19 FROM t2; +--source include/wait_condition.inc # If you want to do manual testing of the mixed mode regarding UDFs (not # testable automatically as quite platform- and compiler-dependent), diff --git a/mysql-test/suite/rpl/t/rpl_temporary.test b/mysql-test/suite/rpl/t/rpl_temporary.test index 852dfdbc25c..6619f4518b9 100644 --- a/mysql-test/suite/rpl/t/rpl_temporary.test +++ b/mysql-test/suite/rpl/t/rpl_temporary.test @@ -60,23 +60,24 @@ insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); connection con1; create temporary table t3(f int); insert into t3 select * from t1 where f<6; -sleep 1; +let $wait_condition= SELECT COUNT(*) = 5 FROM t3; +--source include/wait_condition.inc connection con2; create temporary table t3(f int); -sleep 1; connection con1; insert into t2 select count(*) from t3; -sleep 1; +let $wait_condition= SELECT COUNT(*) = 1 FROM t2; +--source include/wait_condition.inc connection con2; insert into t3 select * from t1 where f>=4; -sleep 1; +let $wait_condition= SELECT COUNT(*) = 7 FROM t3; +--source include/wait_condition.inc connection con1; drop temporary table t3; -sleep 1; connection con2; insert into t2 select count(*) from t3; diff --git a/mysql-test/suite/rpl/t/rpl_temporary_errors.test b/mysql-test/suite/rpl/t/rpl_temporary_errors.test index 6a57f3cc167..f38ed29f7d4 100644 --- a/mysql-test/suite/rpl/t/rpl_temporary_errors.test +++ b/mysql-test/suite/rpl/t/rpl_temporary_errors.test @@ -8,6 +8,9 @@ INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4); --echo **** On Slave **** sync_slave_with_master; SHOW STATUS LIKE 'Slave_retried_transactions'; +# since bug#31552/31609 idempotency is not default any longer. In order +# the following UPDATE t1 to pass the mode is switched temprorarily +set @@global.slave_exec_mode= 'IDEMPOTENT'; UPDATE t1 SET a = 5, b = 47 WHERE a = 1; SELECT * FROM t1; --echo **** On Master **** @@ -17,9 +20,10 @@ SELECT * FROM t1; #SHOW BINLOG EVENTS; --echo **** On Slave **** sync_slave_with_master; +set @@global.slave_exec_mode= default; SHOW STATUS LIKE 'Slave_retried_transactions'; SELECT * FROM t1; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; DROP TABLE t1; --echo **** On Master **** diff --git a/mysql-test/suite/rpl/t/rpl_trigger.test b/mysql-test/suite/rpl/t/rpl_trigger.test index 4a496ea4923..911110d17dc 100644 --- a/mysql-test/suite/rpl/t/rpl_trigger.test +++ b/mysql-test/suite/rpl/t/rpl_trigger.test @@ -101,10 +101,12 @@ let $time=`select a from t1`; # - dump definers on the slave; SELECT routine_name, definer -FROM information_schema.routines; +FROM information_schema.routines +WHERE routine_name = 'bug12480'; SELECT trigger_name, definer -FROM information_schema.triggers; +FROM information_schema.triggers +WHERE trigger_name = 't1_first'; save_master_pos; connection slave; @@ -119,10 +121,12 @@ select "--- On slave --" as ""; # item. SELECT routine_name, definer -FROM information_schema.routines; +FROM information_schema.routines +WHERE routine_name = 'bug12480'; SELECT trigger_name, definer -FROM information_schema.triggers; +FROM information_schema.triggers +WHERE trigger_name = 't1_first'; select a=b && a=c from t1; --disable_query_log diff --git a/mysql-test/suite/rpl/t/rpl_user.test b/mysql-test/suite/rpl/t/rpl_user.test new file mode 100644 index 00000000000..b8fe41d03c4 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_user.test @@ -0,0 +1,61 @@ +# BUG#33862 completely failed DROP USER statement gets replicated + +--source include/master-slave.inc + +# +# remove all users will be used in the test +# +connection master; +set session sql_log_bin=0; +delete from mysql.user where Host='fakehost'; +set session sql_log_bin=1; + +connection slave; +set session sql_log_bin=0; +delete from mysql.user where Host='fakehost'; +set session sql_log_bin=1; + +# +# Test create user +# +connection master; +create user 'foo'@'fakehost'; +--error ER_CANNOT_USER +create user 'foo'@'fakehost', 'bar'@'fakehost'; +--error ER_CANNOT_USER +create user 'foo'@'fakehost', 'bar'@'fakehost'; + +sync_slave_with_master; +select Host,User from mysql.user where Host='fakehost'; + +# +# Test rename user +# +connection master; +rename user 'foo'@'fakehost' to 'foofoo'@'fakehost'; +--error ER_CANNOT_USER +rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'bar'@'fakehost' to 'barbar'@'fakehost'; +--error ER_CANNOT_USER +rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'not_exist_user2'@'fakehost' to 'barfoo'@'fakehost'; + +sync_slave_with_master; +select Host,User from mysql.user where Host='fakehost'; + +# +# Test drop user +# +connection master; +drop user 'foofoo'@'fakehost'; +--error ER_CANNOT_USER +drop user 'not_exist_user1'@'fakehost', 'barbar'@'fakehost'; +--error ER_CANNOT_USER +drop user 'not_exist_user1'@'fakehost', 'not_exist_user2'@'fakehost'; + +sync_slave_with_master; +select Host,User from mysql.user where Host='fakehost'; + +# +# show the binlog events on the master +# +connection master; +source include/show_binlog_events.inc; diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_ctype_ucs2_def.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_ctype_ucs2_def.result index 2f9dc4ae616..75151f45419 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_ctype_ucs2_def.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_ctype_ucs2_def.result @@ -1,3 +1,9 @@ +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; show variables like 'collation_server'; Variable_name Value collation_server ucs2_unicode_ci @@ -5,5 +11,17 @@ show variables like "%character_set_ser%"; Variable_name Value character_set_server ucs2 DROP TABLE IF EXISTS t1; -create table t1 (a int); +create table t1 (a int) ENGINE=NDB; drop table t1; +CREATE TABLE `t1` ( `nid` int(11) NOT NULL default '0', +`nom` char(4) default NULL, +`prenom` char(4) default NULL, +PRIMARY KEY (`nid`)) +ENGINE=ndbcluster; +INSERT INTO t1 VALUES(1,"XYZ1","ABC1"); +select * from t1 order by nid; +nid nom prenom +1 XYZ1 ABC1 +select * from t1 order by nid; +nid nom prenom +1 XYZ1 ABC1 diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_stm_innodb.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_stm_innodb.result index 426a09f945c..7008dc60d96 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_stm_innodb.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_stm_innodb.result @@ -22,11 +22,11 @@ from mysql.ndb_apply_status; show binlog events from <start_pos> limit 1; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 <start_pos> Query 1 # use `test`; insert into t1 values (1,2) +master-bin.000001 <start_pos> Query 1 # use `test`; BEGIN show binlog events from <start_pos> limit 1,1; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Xid 1 445 COMMIT /* XID */ +master-bin.000001 # Query 1 486 use `test`; insert into t1 values (1,2) begin; insert into t1 values (2,3); diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_transaction.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_transaction.result new file mode 100644 index 00000000000..bbd0a873dc8 --- /dev/null +++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_transaction.result @@ -0,0 +1,110 @@ +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; +CREATE TABLE tmyisam (a int) ENGINE = MYISAM; +CREATE TABLE tinnodb (a int) ENGINE = INNODB; +CREATE TABLE tndb (a int) ENGINE = NDB; +SHOW CREATE TABLE tmyisam; +Table Create Table +tmyisam CREATE TABLE `tmyisam` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SHOW CREATE TABLE tinnodb; +Table Create Table +tinnodb CREATE TABLE `tinnodb` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SHOW CREATE TABLE tndb; +Table Create Table +tndb CREATE TABLE `tndb` ( + `a` int(11) DEFAULT NULL +) ENGINE=ndbcluster DEFAULT CHARSET=latin1 +==== Test 1: Non-XA Engines ==== +--- on master --- +SET AUTOCOMMIT = 1; +INSERT INTO tndb VALUES (1); +INSERT INTO tmyisam VALUES (1); +BEGIN; +INSERT INTO tndb VALUES (2); +INSERT INTO tndb VALUES (3); +COMMIT; +BEGIN; +INSERT INTO tmyisam VALUES (2); +INSERT INTO tmyisam VALUES (3); +COMMIT; +BEGIN; +INSERT INTO tndb VALUES (4); +INSERT INTO tmyisam VALUES (4); +COMMIT; +BEGIN; +INSERT INTO tndb VALUES (5); +INSERT INTO tndb VALUES (6); +ROLLBACK; +BEGIN; +INSERT INTO tmyisam VALUES (5); +INSERT INTO tmyisam VALUES (6); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +BEGIN; +INSERT INTO tndb VALUES (7); +INSERT INTO tmyisam VALUES (7); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +SELECT * FROM tndb ORDER BY a; +a +1 +2 +3 +4 +SELECT * FROM tmyisam ORDER BY a; +a +1 +2 +3 +4 +5 +6 +7 +--- on slave --- +SELECT * FROM tndb ORDER BY a; +a +1 +2 +3 +4 +SELECT * FROM tmyisam ORDER BY a; +a +1 +2 +3 +4 +5 +6 +7 +==== Test 2: Master crash before writing XID event on XA engine ==== +--- on master --- +INSERT INTO tinnodb VALUES (1); +SELECT * FROM tinnodb ORDER BY a; +a +1 +--- on slave --- +STOP SLAVE; +SELECT "" AS Slave_IO_State; +Slave_IO_State + +SELECT "" AS Last_SQL_Error; +Last_SQL_Error + +SELECT "" AS Last_IO_Error; +Last_IO_Error + +SELECT * FROM tinnodb ORDER BY a; +a +--- on master --- +DROP TABLE tmyisam, tinnodb, tndb; +DROP TABLE tmyisam, tinnodb, tndb; diff --git a/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result b/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result index f176d4eb52a..08232817e92 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result @@ -370,6 +370,7 @@ C1 C2 1 3 2 6 3 9 +set @@global.slave_exec_mode= 'IDEMPOTENT'; --- on master: new values inserted --- INSERT INTO t7 VALUES (1,2), (2,4), (3,6); SELECT * FROM t7 ORDER BY C1; @@ -377,6 +378,7 @@ C1 C2 1 2 2 4 3 6 +set @@global.slave_exec_mode= default; --- on slave: old values should be overwritten by replicated values --- SELECT * FROM t7 ORDER BY C1; C1 C2 @@ -406,8 +408,10 @@ a b c 2 4 6 3 6 9 99 99 99 +set @@global.slave_exec_mode= 'IDEMPOTENT'; --- on master --- INSERT INTO t8 VALUES (2,4,8); +set @@global.slave_exec_mode= default; --- on slave --- SELECT * FROM t8 ORDER BY a; a b c @@ -426,10 +430,12 @@ START SLAVE; **** On Master **** INSERT INTO t1 VALUES ('K','K'), ('L','L'), ('M','M'); **** On Master **** +set @@global.slave_exec_mode= 'IDEMPOTENT'; DELETE FROM t1 WHERE C1 = 'L'; DELETE FROM t1; SELECT COUNT(*) FROM t1 ORDER BY c1,c2; COUNT(*) 0 +set @@global.slave_exec_mode= default; Last_SQL_Error 0 SELECT COUNT(*) FROM t1 ORDER BY c1,c2; diff --git a/mysql-test/suite/rpl_ndb/t/disabled.def b/mysql-test/suite/rpl_ndb/t/disabled.def index bb701b9dc3e..0b0ce3df51b 100644 --- a/mysql-test/suite/rpl_ndb/t/disabled.def +++ b/mysql-test/suite/rpl_ndb/t/disabled.def @@ -14,7 +14,6 @@ rpl_ndb_2innodb : Bug #32648 Test failure between NDB Cluster and other engines rpl_ndb_2myisam : Bug #32648 Test failure between NDB Cluster and other engines rpl_ndb_2other : Bug #32648 Test failure between NDB Cluster and other engines -rpl_ndb_ctype_ucs2_def : BUG#27404 util thd mysql_parse sig11 when mysqld default multibyte charset rpl_ndb_extraColMaster : BUG#30854 : Tables name show as binary in slave err msg on vm-win2003-64-b and Solaris rpl_ndb_mix_innodb : Bug #32720 Test rpl_ndb_mix_innodb fails on SPARC and PowerPC diff --git a/mysql-test/suite/rpl_ndb/t/rpl_ndb_transaction-master.opt b/mysql-test/suite/rpl_ndb/t/rpl_ndb_transaction-master.opt new file mode 100644 index 00000000000..5411960b4aa --- /dev/null +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_transaction-master.opt @@ -0,0 +1 @@ +--innodb --debug=d,do_not_write_xid diff --git a/mysql-test/suite/rpl_ndb/t/rpl_ndb_transaction-slave.opt b/mysql-test/suite/rpl_ndb/t/rpl_ndb_transaction-slave.opt new file mode 100644 index 00000000000..627becdbfb5 --- /dev/null +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_transaction-slave.opt @@ -0,0 +1 @@ +--innodb diff --git a/mysql-test/suite/rpl_ndb/t/rpl_ndb_transaction.test b/mysql-test/suite/rpl_ndb/t/rpl_ndb_transaction.test new file mode 100644 index 00000000000..3c7c15926a4 --- /dev/null +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_transaction.test @@ -0,0 +1,131 @@ +# Tests that transactions are replicated correctly, with various +# combinations of non-transactional and transactional non-XA tables. +# Also tests that an XA transaction where the master crashes just +# before writing the XID log event is executed correctly. See below +# for implementation details. + +source include/ndb_master-slave.inc; +source include/have_ndb.inc; +source include/have_debug.inc; + +CREATE TABLE tmyisam (a int) ENGINE = MYISAM; +CREATE TABLE tinnodb (a int) ENGINE = INNODB; +CREATE TABLE tndb (a int) ENGINE = NDB; + +SHOW CREATE TABLE tmyisam; +SHOW CREATE TABLE tinnodb; +SHOW CREATE TABLE tndb; + + +--echo ==== Test 1: Non-XA Engines ==== +# Test that everything works fine with non-XA engines. We just try +# all ways to do transactions involving ndb and/or myisam, with +# rollback or commit. + +--echo --- on master --- + +SET AUTOCOMMIT = 1; + +INSERT INTO tndb VALUES (1); +INSERT INTO tmyisam VALUES (1); + +BEGIN; +INSERT INTO tndb VALUES (2); +INSERT INTO tndb VALUES (3); +COMMIT; + +BEGIN; +INSERT INTO tmyisam VALUES (2); +INSERT INTO tmyisam VALUES (3); +COMMIT; + +BEGIN; +INSERT INTO tndb VALUES (4); +INSERT INTO tmyisam VALUES (4); +COMMIT; + +BEGIN; +INSERT INTO tndb VALUES (5); +INSERT INTO tndb VALUES (6); +ROLLBACK; + +BEGIN; +INSERT INTO tmyisam VALUES (5); +INSERT INTO tmyisam VALUES (6); +--warning 1196 +ROLLBACK; + +BEGIN; +INSERT INTO tndb VALUES (7); +INSERT INTO tmyisam VALUES (7); +--warning 1196 +ROLLBACK; + +SELECT * FROM tndb ORDER BY a; +SELECT * FROM tmyisam ORDER BY a; + +--echo --- on slave --- +--sync_slave_with_master +SELECT * FROM tndb ORDER BY a; +SELECT * FROM tmyisam ORDER BY a; + + +--echo ==== Test 2: Master crash before writing XID event on XA engine ==== +# We now want to test the following scenario, to verify that BUG#26395 +# has been fixed: + +# "master and slave have a transactional table that uses XA. Master +# has AUTOCOMMIT on and executes a statement (in this case an +# INSERT). Master crashes just before writing the XID event." + +# In this scenario, master will roll back, so slave should not execute +# the statement, and slave should roll back later when master is +# restarted. + +# However, we want the master to be alive so that we are sure it +# replicates the statement to the slave. So in the test case, we must +# therefore not crash the master. Instead, we fake the crash by just +# not writing the XID event to the binlog. This is done by the +# --debug=d,do_not_write_xid flag in the .opt file. + +# So, unlike if the master had crashed, the master *will* execute the +# statement. But the slave should not execute it. Hence, after the +# first test is executed, the expected result on master is a table +# with one row, and on slave a table with no rows. + +# To simulate the slave correctly, we wait until everything up to the +# XID is replicated. We cannot sync_slave_with_master, because that +# would wait for the transaction to end. Instead, we wait for +# "sufficiently long time". Then we stop the slave. + +# Note: since this puts the master binlog in an inconsistent state, +# this should be the last test of the file. + +--echo --- on master --- +--connection master + +INSERT INTO tinnodb VALUES (1); +SELECT * FROM tinnodb ORDER BY a; + +--echo --- on slave --- +--connection slave +--sleep 3 +STOP SLAVE; +source include/wait_for_slave_to_stop.inc; +let $tmp= query_get_value("SHOW SLAVE STATUS", Slave_IO_State, 1); +eval SELECT "$tmp" AS Slave_IO_State; +let $tmp= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1); +eval SELECT "$tmp" AS Last_SQL_Error; +let $tmp= query_get_value("SHOW SLAVE STATUS", Last_IO_Error, 1); +eval SELECT "$tmp" AS Last_IO_Error; +SELECT * FROM tinnodb ORDER BY a; + +# Clean up. We cannot do it on master and replicate over, because +# master binlog is in a bad state after last test. So we do it both on +# master and on slave. +--echo --- on master --- +connection master; +DROP TABLE tmyisam, tinnodb, tndb; + +connection slave; +DROP TABLE tmyisam, tinnodb, tndb; diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test index 99e9b783d55..ff92c743960 100644 --- a/mysql-test/t/auto_increment.test +++ b/mysql-test/t/auto_increment.test @@ -149,6 +149,7 @@ delete from t1 where a=0; update t1 set a=0 where b=5; select * from t1 order by b; delete from t1 where a=0; +--error 1048 update t1 set a=NULL where b=6; update t1 set a=300 where b=7; SET SQL_MODE=''; @@ -164,6 +165,7 @@ delete from t1 where a=0; update t1 set a=0 where b=12; select * from t1 order by b; delete from t1 where a=0; +--error 1048 update t1 set a=NULL where b=13; update t1 set a=500 where b=14; select * from t1 order by b; diff --git a/mysql-test/t/bdb_notembedded.test b/mysql-test/t/bdb_notembedded.test deleted file mode 100644 index 24e64ebbfb2..00000000000 --- a/mysql-test/t/bdb_notembedded.test +++ /dev/null @@ -1,38 +0,0 @@ --- source include/not_embedded.inc --- source include/have_bdb.inc - -# -# Bug #16206: Superfluous COMMIT event in binlog when updating BDB in autocommit mode -# -set autocommit=1; - -let $VERSION=`select version()`; - -reset master; -create table bug16206 (a int); -insert into bug16206 values(1); -start transaction; -insert into bug16206 values(2); -commit; ---replace_result $VERSION VERSION ---replace_column 1 f 2 n 5 n -show binlog events; -drop table bug16206; - -reset master; -create table bug16206 (a int) engine= bdb; -insert into bug16206 values(0); -insert into bug16206 values(1); -start transaction; -insert into bug16206 values(2); -commit; -insert into bug16206 values(3); ---replace_result $VERSION VERSION ---replace_column 1 f 2 n 5 n -show binlog events; -drop table bug16206; - -set autocommit=0; - - ---echo End of 5.0 tests diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 322be2b7b8e..826e00bf74f 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -598,5 +598,46 @@ insert into t1 values (''),(''); select group_concat(distinct f1) from t1; select group_concat(f1) from t1; drop table t1; +# Bug#32798: DISTINCT in GROUP_CONCAT clause fails when ordering by a column +# with null values +#' +CREATE TABLE t1 (a INT, b INT); + +INSERT INTO t1 VALUES (1, 1), (2, 2), (2, 3); + +SELECT GROUP_CONCAT(DISTINCT a ORDER BY b) FROM t1; +SELECT GROUP_CONCAT(DISTINCT a ORDER BY b DESC) FROM t1; +SELECT GROUP_CONCAT(DISTINCT a) FROM t1; + +SELECT GROUP_CONCAT(DISTINCT a + 1 ORDER BY 3 - b) FROM t1; +SELECT GROUP_CONCAT(DISTINCT a + 1 ORDER BY b) FROM t1; +SELECT GROUP_CONCAT(a ORDER BY 3 - b) FROM t1; + +CREATE TABLE t2 (a INT, b INT, c INT, d INT); + +# There is one duplicate in the expression list: 1,10 +# There is one duplicate in ORDER BY list, but that shouldnt matter: 1,10 +INSERT INTO t2 VALUES (1,1, 1,1), (1,1, 2,2), (1,2, 2,1), (2,1, 1,2); + +SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY c, d) FROM t2; +SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY d, c) FROM t2; + +CREATE TABLE t3 (a INT, b INT, c INT); + +INSERT INTO t3 VALUES (1, 1, 1), (2, 1, 2), (3, 2, 1); + +SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY b, c) FROM t3; +SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY c, b) FROM t3; + +SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY a, b) FROM t1; +SELECT GROUP_CONCAT(DISTINCT b, a ORDER BY a, b) FROM t1; +SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY b, a) FROM t1; +SELECT GROUP_CONCAT(DISTINCT b, a ORDER BY a, b) FROM t1; +SELECT GROUP_CONCAT(DISTINCT a ORDER BY a, b) FROM t1; +SELECT GROUP_CONCAT(DISTINCT b ORDER BY b, a) FROM t1; +SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY a) FROM t1; +SELECT GROUP_CONCAT(DISTINCT b, a ORDER BY b) FROM t1; + +DROP TABLE t1, t2, t3; --echo End of 5.0 tests diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 8beed28cfbf..36d360780cf 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -908,5 +908,20 @@ SELECT COUNT(*), a FROM t1; DROP TABLE t1; +# +# Bug #33133: Views are not transparent +# + +set SQL_MODE=ONLY_FULL_GROUP_BY; + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3),(4); +CREATE VIEW v1 AS SELECT a,(a + 1) AS y FROM t1; +EXPLAIN EXTENDED SELECT y FROM v1 GROUP BY v1.y; + +DROP VIEW v1; +DROP TABLE t1; +SET SQL_MODE=DEFAULT; + ### --echo End of 5.0 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 97087abd668..13c5da1285a 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -776,6 +776,13 @@ select DATE_ADD(20071108181000, INTERVAL 1 DAY); select DATE_ADD('20071108', INTERVAL 1 DAY); select DATE_ADD(20071108, INTERVAL 1 DAY); +# +# Bug#32770: LAST_DAY() returns a DATE, but somehow internally keeps +# track of the TIME. +# + +select LAST_DAY('2007-12-06 08:59:19.05') - INTERVAL 1 SECOND; + --echo End of 5.0 tests # diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index 94c2b463aaa..3211db5d6ed 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -790,8 +790,6 @@ drop table t1; SET SQL_MODE = ''; # - -# # Bug #32202: ORDER BY not working with GROUP BY # @@ -824,6 +822,7 @@ SELECT * FROM t1 GROUP BY c2 ORDER BY c2 DESC, c1 DESC; DROP TABLE t1; + --echo End of 5.0 tests # Bug #21174: Index degrades sort performance and # optimizer does not honor IGNORE INDEX. @@ -946,3 +945,51 @@ EXPLAIN SELECT b from t2 GROUP BY b; SELECT b from t2 GROUP BY b; DROP TABLE t1; + +# +# Bug #31797: error while parsing subqueries -- WHERE is parsed as HAVING +# +CREATE TABLE t1 ( a INT, b INT ); + +SELECT b c, (SELECT a FROM t1 WHERE b = c) +FROM t1; + +SELECT b c, (SELECT a FROM t1 WHERE b = c) +FROM t1 +HAVING b = 10; + +--error ER_ILLEGAL_REFERENCE +SELECT MAX(b) c, (SELECT a FROM t1 WHERE b = c) +FROM t1 +HAVING b = 10; + +SET @old_sql_mode = @@sql_mode; +SET @@sql_mode='ONLY_FULL_GROUP_BY'; + +SELECT b c, (SELECT a FROM t1 WHERE b = c) +FROM t1; + +--error ER_NON_GROUPING_FIELD_USED +SELECT b c, (SELECT a FROM t1 WHERE b = c) +FROM t1 +HAVING b = 10; + +--error ER_ILLEGAL_REFERENCE +SELECT MAX(b) c, (SELECT a FROM t1 WHERE b = c) +FROM t1 +HAVING b = 10; + +INSERT INTO t1 VALUES (1, 1); +SELECT b c, (SELECT a FROM t1 WHERE b = c) +FROM t1; + +INSERT INTO t1 VALUES (2, 1); +--error ER_SUBQUERY_NO_1_ROW +SELECT b c, (SELECT a FROM t1 WHERE b = c) +FROM t1; + +DROP TABLE t1; +SET @@sql_mode = @old_sql_mode; + + + diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 1afc105e34e..eb364c60e71 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -43,6 +43,7 @@ select "--- Local --" as ""; # --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000001 # this should not fail but shouldn't produce any working statements @@ -50,6 +51,7 @@ select "--- Local --" as ""; select "--- Broken LOAD DATA --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000002 2> /dev/null # this should show almost nothing @@ -57,6 +59,7 @@ select "--- Broken LOAD DATA --" as ""; select "--- --database --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --database=nottest $MYSQLTEST_VARDIR/log/master-bin.000001 2> /dev/null # this test for position option @@ -64,6 +67,7 @@ select "--- --database --" as ""; select "--- --position --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --position=239 $MYSQLTEST_VARDIR/log/master-bin.000002 # These are tests for remote binlog. @@ -75,6 +79,7 @@ select "--- Remote --" as ""; # This is broken now --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 # This is broken too @@ -82,6 +87,7 @@ select "--- Remote --" as ""; select "--- Broken LOAD DATA --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 2> /dev/null # And this too ! (altough it is documented) @@ -89,6 +95,7 @@ select "--- Broken LOAD DATA --" as ""; select "--- --database --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --database=nottest master-bin.000001 2> /dev/null # Strangely but this works @@ -96,6 +103,7 @@ select "--- --database --" as ""; select "--- --position --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --position=239 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 # Bug#7853 (mysqlbinlog does not accept input from stdin) @@ -103,9 +111,11 @@ select "--- --position --" as ""; select "--- reading stdin --" as ""; --enable_query_log --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR +--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form - < $MYSQL_TEST_DIR/std_data/trunc_binlog.000001 --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR +--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --position=79 - < $MYSQL_TEST_DIR/std_data/trunc_binlog.000001 drop table t1,t2; @@ -169,6 +179,7 @@ call p1(); drop procedure p1; --error 1305 call p1(); +--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form $MYSQLTEST_VARDIR/log/master-bin.000008 --exec $MYSQL_BINLOG --short-form $MYSQLTEST_VARDIR/log/master-bin.000008 | $MYSQL call p1(); @@ -204,6 +215,7 @@ select hex(a) from t1; drop table t1; flush logs; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000010 # @@ -282,4 +294,31 @@ connection default; DROP DATABASE mysqltest1; DROP USER untrusted@localhost; +--echo BUG#32580: mysqlbinlog cannot read binlog event with user variables + +# Testing that various kinds of events can be read and restored properly. + +connection default; +USE test; +SET BINLOG_FORMAT = STATEMENT; +FLUSH LOGS; +CREATE TABLE t1 (a_real FLOAT, an_int INT, a_decimal DECIMAL(5,2), a_string CHAR(32)); +SET @a_real = rand(20) * 1000; +SET @an_int = 1000; +SET @a_decimal = CAST(rand(19) * 999 AS DECIMAL(5,2)); +SET @a_string = 'Just a test'; +INSERT INTO t1 VALUES (@a_real, @an_int, @a_decimal, @a_string); +FLUSH LOGS; +query_vertical SELECT * FROM t1; +DROP TABLE t1; + +echo >> mysqlbinlog var/log/master-bin.000019 > var/tmp/bug32580.sql; +exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/log/master-bin.000019 > $MYSQLTEST_VARDIR/tmp/bug32580.sql; +echo >> mysql test < var/tmp/bug32580.sql; +exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug32580.sql; +remove_file $MYSQLTEST_VARDIR/tmp/bug32580.sql; + +query_vertical SELECT * FROM t1; +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/t/mysqlbinlog2.test b/mysql-test/t/mysqlbinlog2.test index be9397aafee..2ac16f4c590 100644 --- a/mysql-test/t/mysqlbinlog2.test +++ b/mysql-test/t/mysqlbinlog2.test @@ -42,7 +42,7 @@ select "--- Local --" as ""; # --replace_regex /[[:<:]][0-9]{6} [0-9 ][0-9]:[0-9]{2}:[0-9]{2}[[:>:]]/{yymmdd} {HH:MM:SS}/ /=[0-9]+ /={integer} / /# at [0-9]+/# at {pos}/ /(pos:?) [0-9]+/\1 {pos}/ /binlog v [0-9]+, server v [^ ]* created/binlog v #, server v ## created/ ---exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/log/master-bin.000001 +--exec $MYSQL_BINLOG --base64-output=never $MYSQLTEST_VARDIR/log/master-bin.000001 --disable_query_log select "--- offset --" as ""; diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index 58d6aef1b90..ba13a315cb8 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -57,7 +57,7 @@ insert into t_bug25347 values (1),(2),(3); 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 EOF +--write_file $MYSQLTEST_VARDIR/master-data/d_bug25347/t_bug25347.MYI EOF --exec $MYSQL_CHECK --repair --databases d_bug25347 --error 130 diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test index 2878b54c357..ddf6b8870fa 100644 --- a/mysql-test/t/null.test +++ b/mysql-test/t/null.test @@ -61,7 +61,9 @@ drop table t1; # CREATE TABLE t1 (a varchar(16) NOT NULL default '', b smallint(6) NOT NULL default 0, c datetime NOT NULL default '0000-00-00 00:00:00', d smallint(6) NOT NULL default 0); INSERT INTO t1 SET a = "", d= "2003-01-14 03:54:55"; +--error 1048 UPDATE t1 SET d=1/NULL; +--error 1048 UPDATE t1 SET d=NULL; --error 1048 INSERT INTO t1 (a) values (null); diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test index 9170308a4f2..800d717cf6b 100644 --- a/mysql-test/t/parser.test +++ b/mysql-test/t/parser.test @@ -657,3 +657,23 @@ CREATE TABLE t1 (a INT, b DATETIME); INSERT INTO t1 VALUES (INTERVAL(3,2,1) + 1, "1997-12-31 23:59:59" + INTERVAL 1 SECOND); SELECT * FROM t1 WHERE a = INTERVAL(3,2,1) + 1; DROP TABLE t1; + +# +# Bug#28317 Left Outer Join with {oj outer-join} +# + +--disable_warnings +DROP TABLE IF EXISTS t1,t2,t3; +--enable_warnings +CREATE TABLE t1 (a1 INT, a2 INT, a3 INT, a4 DATETIME); +CREATE TABLE t2 LIKE t1; +CREATE TABLE t3 LIKE t1; +SELECT t1.* FROM t1 AS t0, { OJ t2 INNER JOIN t1 ON (t1.a1=t2.a1) } WHERE t0.a3=2; +SELECT t1.*,t2.* FROM { OJ ((t1 INNER JOIN t2 ON (t1.a1=t2.a2)) LEFT OUTER JOIN t3 ON t3.a3=t2.a1)}; +SELECT t1.*,t2.* FROM { OJ ((t1 LEFT OUTER JOIN t2 ON t1.a3=t2.a2) INNER JOIN t3 ON (t3.a1=t2.a2))}; +SELECT t1.*,t2.* FROM { OJ (t1 LEFT OUTER JOIN t2 ON t1.a1=t2.a2) CROSS JOIN t3 ON (t3.a2=t2.a3)}; +SELECT * FROM {oj t1 LEFT OUTER JOIN t2 ON t1.a1=t2.a3} WHERE t1.a2 > 10; +SELECT {fn CONCAT(a1,a2)} FROM t1; +UPDATE t3 SET a4={d '1789-07-14'} WHERE a1=0; +SELECT a1, a4 FROM t2 WHERE a4 LIKE {fn UCASE('1789-07-14')}; +DROP TABLE t1, t2, t3; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 890999cdc08..48a63dfb67c 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -1316,6 +1316,5 @@ SELECT 1 FROM t1 GROUP BY (SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1); DROP TABLE t1; - --echo End of 5.1 tests diff --git a/mysql-test/t/query_cache_debug.test b/mysql-test/t/query_cache_debug.test new file mode 100644 index 00000000000..b741eea0b29 --- /dev/null +++ b/mysql-test/t/query_cache_debug.test @@ -0,0 +1,46 @@ +--source include/not_embedded.inc +--source include/have_query_cache.inc +--source include/have_debug.inc + +# +# Bug #30887 Server crashes on SET GLOBAL query_cache_size=0 +# +flush status; +set query_cache_type=DEMAND; +set global query_cache_size= 1024*1024*512; +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (a varchar(100)); +insert into t1 values ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +connect (bug30887con1, localhost, root, ,test); +connect (bug30887con2, localhost, root, ,test); + +connection bug30887con1; +--echo Activate debug hook and attempt to retrieve the statement from the cache. +set session debug='+d,wait_in_query_cache_insert'; +--send select SQL_CACHE * from t1; + +connection default; +let $wait_condition= select count(*)= 1 from information_schema.processlist where state= 'wait_in_query_cache_insert'; +--source include/wait_condition.inc + +connection bug30887con2; +--echo On a second connection; clear the query cache. +show status like 'Qcache_queries_in_cache'; +set global query_cache_size= 0; + +connection default; +--echo Signal the debug hook to release the lock. +select id from information_schema.processlist where state='wait_in_query_cache_insert' into @thread_id; +kill query @thread_id; + +--echo Show query cache status. +show status like 'Qcache_queries_in_cache'; + +disconnect bug30887con1; +disconnect bug30887con2; +set global query_cache_size= 0; +use test; +drop table t1; + diff --git a/mysql-test/t/skip_grants.test b/mysql-test/t/skip_grants.test index 72a073ac541..6f4d23e1e14 100644 --- a/mysql-test/t/skip_grants.test +++ b/mysql-test/t/skip_grants.test @@ -122,16 +122,6 @@ select count(*) from information_schema.COLUMN_PRIVILEGES; select count(*) from information_schema.SCHEMA_PRIVILEGES; select count(*) from information_schema.TABLE_PRIVILEGES; select count(*) from information_schema.USER_PRIVILEGES; -# -# Bug #32020: loading udfs while --skip-grant-tables is enabled causes out of -# memory errors -# - ---error ER_CANT_INITIALIZE_UDF -CREATE FUNCTION a RETURNS STRING SONAME ''; ---error ER_SP_DOES_NOT_EXIST -DROP FUNCTION a; - --echo End of 5.0 tests --echo # diff --git a/mysql-test/t/sp-code.test b/mysql-test/t/sp-code.test index 66d5323d2e2..84f0201c808 100644 --- a/mysql-test/t/sp-code.test +++ b/mysql-test/t/sp-code.test @@ -520,6 +520,83 @@ drop table t1; drop procedure proc_26977_broken; drop procedure proc_26977_works; +# +# Bug#33618 Crash in sp_rcontext +# + +--disable_warnings +drop procedure if exists proc_33618_h; +drop procedure if exists proc_33618_c; +--enable_warnings + +delimiter //; + +create procedure proc_33618_h(num int) +begin + declare count1 int default '0'; + declare vb varchar(30); + declare last_row int; + + while(num>=1) do + set num=num-1; + begin + declare cur1 cursor for select `a` from t_33618; + declare continue handler for not found set last_row = 1; + set last_row:=0; + open cur1; + rep1: + repeat + begin + declare exit handler for 1062 begin end; + fetch cur1 into vb; + if (last_row = 1) then + ## should generate a hpop instruction here + leave rep1; + end if; + end; + until last_row=1 + end repeat; + close cur1; + end; + end while; +end// + +create procedure proc_33618_c(num int) +begin + declare count1 int default '0'; + declare vb varchar(30); + declare last_row int; + + while(num>=1) do + set num=num-1; + begin + declare cur1 cursor for select `a` from t_33618; + declare continue handler for not found set last_row = 1; + set last_row:=0; + open cur1; + rep1: + repeat + begin + declare cur2 cursor for select `b` from t_33618; + fetch cur1 into vb; + if (last_row = 1) then + ## should generate a cpop instruction here + leave rep1; + end if; + end; + until last_row=1 + end repeat; + close cur1; + end; + end while; +end// +delimiter ;// + +show procedure code proc_33618_h; +show procedure code proc_33618_c; + +drop procedure proc_33618_h; +drop procedure proc_33618_c; --echo End of 5.0 tests. diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 606c2a673bc..286722df65c 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -2306,6 +2306,69 @@ drop table t2; --echo End of 5.1 tests # +# Bug#33983 (Stored Procedures: wrong end <label> syntax is accepted) +# + +--disable_warnings +drop procedure if exists proc_33983_a; +drop procedure if exists proc_33983_b; +drop procedure if exists proc_33983_c; +drop procedure if exists proc_33983_d; +--enable_warnings + +delimiter |; + +--error ER_SP_LABEL_MISMATCH +create procedure proc_33983_a() +begin + label1: + begin + label2: + begin + select 1; + end label1; + end; +end| + +--error ER_SP_LABEL_MISMATCH +create procedure proc_33983_b() +begin + label1: + repeat + label2: + repeat + select 1; + until FALSE end repeat label1; + until FALSE end repeat; +end| + +--error ER_SP_LABEL_MISMATCH +create procedure proc_33983_c() +begin + label1: + while TRUE do + label2: + while TRUE do + select 1; + end while label1; + end while; +end| + +--error ER_SP_LABEL_MISMATCH +create procedure proc_33983_d() +begin + label1: + loop + label2: + loop + select 1; + end loop label1; + end loop; +end| + +delimiter ;| + +# # BUG#NNNN: New bug synopsis # #--disable_warnings diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 004e1c4ddd2..6dc2f906d45 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -7902,7 +7902,86 @@ use test; ########################################################################### ---echo End of 5.0 tests +# +# Bug#29770 Two handlers are allowed to catch an error in an stored procedure. +# + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP PROCEDURE IF EXISTS bug29770; +--enable_warnings + +CREATE TABLE t1(a int); +delimiter |; +CREATE PROCEDURE bug29770() +BEGIN + DECLARE CONTINUE HANDLER FOR SQLSTATE '42S22' SET @state:= 'run'; + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @exception:= 'run'; + SELECT x FROM t1; +END| +delimiter ;| +CALL bug29770(); +SELECT @state, @exception; +DROP TABLE t1; +DROP PROCEDURE bug29770; + +# +# Bug#33618 Crash in sp_rcontext +# + +use test; + +--disable_warnings +drop table if exists t_33618; +drop procedure if exists proc_33618; +--enable_warnings + +create table t_33618 (`a` int, unique(`a`), `b` varchar(30)) engine=myisam; +insert into t_33618 (`a`,`b`) values (1,'1'),(2,'2'); + +delimiter //; + +create procedure proc_33618(num int) +begin + declare count1 int default '0'; + declare vb varchar(30); + declare last_row int; + + while(num>=1) do + set num=num-1; + begin + declare cur1 cursor for select `a` from t_33618; + declare continue handler for not found set last_row = 1; + set last_row:=0; + open cur1; + rep1: + repeat + begin + declare exit handler for 1062 begin end; + fetch cur1 into vb; + if (last_row = 1) then + leave rep1; + end if; + end; + until last_row=1 + end repeat; + close cur1; + end; + end while; +end// + +delimiter ;// + +call proc_33618(20); + +drop table t_33618; +drop procedure proc_33618; + +########################################################################### + +--echo # ------------------------------------------------------------------ +--echo # -- End of 5.0 tests +--echo # ------------------------------------------------------------------ ########################################################################### @@ -8056,4 +8135,6 @@ DROP FUNCTION f1; ########################################################################### ---echo End of 5.1 tests +--echo # ------------------------------------------------------------------ +--echo # -- End of 5.1 tests +--echo # ------------------------------------------------------------------ diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 6d6490d0ebc..7684aaab6dc 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3136,6 +3136,82 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION DROP TABLE t1,t2; +# +# Bug#33675: Usage of an uninitialized memory by filesort in a subquery +# caused server crash. +# +create table t1(f11 int, f12 int); +create table t2(f21 int unsigned not null, f22 int, f23 varchar(10)); +insert into t1 values(1,1),(2,2), (3, 3); +let $i=10000; +--disable_query_log +--disable_warnings +while ($i) +{ + eval insert into t2 values (-1 , $i/5000 + 1, '$i'); + dec $i; +} +--enable_warnings +--enable_query_log +set session sort_buffer_size= 33*1024; +select count(*) from t1 where f12 = +(select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1); + +drop table t1,t2; + +# +# BUG#33794 "MySQL crashes executing specific query on specific dump" +# +CREATE TABLE t4 ( + f7 varchar(32) collate utf8_bin NOT NULL default '', + f10 varchar(32) collate utf8_bin default NULL, + PRIMARY KEY (f7) +); +INSERT INTO t4 VALUES(1,1), (2,null); + +CREATE TABLE t2 ( + f4 varchar(32) collate utf8_bin NOT NULL default '', + f2 varchar(50) collate utf8_bin default NULL, + f3 varchar(10) collate utf8_bin default NULL, + PRIMARY KEY (f4), + UNIQUE KEY uk1 (f2) +); +INSERT INTO t2 VALUES(1,1,null), (2,2,null); + +CREATE TABLE t1 ( + f8 varchar(32) collate utf8_bin NOT NULL default '', + f1 varchar(10) collate utf8_bin default NULL, + f9 varchar(32) collate utf8_bin default NULL, + PRIMARY KEY (f8) +); +INSERT INTO t1 VALUES (1,'P',1), (2,'P',1), (3,'R',2); + +CREATE TABLE t3 ( + f6 varchar(32) collate utf8_bin NOT NULL default '', + f5 varchar(50) collate utf8_bin default NULL, + PRIMARY KEY (f6) +); +INSERT INTO t3 VALUES (1,null), (2,null); + +SELECT + IF(t1.f1 = 'R', a1.f2, t2.f2) AS a4, + IF(t1.f1 = 'R', a1.f3, t2.f3) AS f3, + SUM( + IF( + (SELECT VPC.f2 + FROM t2 VPC, t4 a2, t2 a3 + WHERE + VPC.f4 = a2.f10 AND a3.f2 = a4 + LIMIT 1) IS NULL, + 0, + t3.f5 + ) + ) AS a6 +FROM + t2, t3, t1 JOIN t2 a1 ON t1.f9 = a1.f4 +GROUP BY a4; + +DROP TABLE t1, t2, t3, t4; --echo End of 5.0 tests. @@ -3165,9 +3241,11 @@ SELECT a FROM t1 t0 SET @@sql_mode=default; DROP TABLE t1; +# # Bug#20835 (literal string with =any values) # 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; + diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index d714229c217..9bc428c3715 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -213,6 +213,14 @@ INSERT INTO t1 VALUES ('1000-00-00'); SET SQL_MODE=DEFAULT; DROP TABLE t1,t2; +# +# Bug #31990: MINUTE() and SECOND() return bogus results when used on a DATE +# + +CREATE TABLE t1 SELECT curdate() AS f1; +SELECT hour(f1), minute(f1), second(f1) FROM t1; +DROP TABLE t1; + --echo End of 5.0 tests # diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test index 807d1e6b01e..6841b3cdd68 100644 --- a/mysql-test/t/type_decimal.test +++ b/mysql-test/t/type_decimal.test @@ -478,4 +478,47 @@ select round(a,b) as c from t1 order by c; DROP TABLE t1, t2, t3, t4; +# +# Bug #33143: Incorrect ORDER BY for ROUND()/TRUNCATE() result +# + +CREATE TABLE t1( a DECIMAL(4, 3), b INT ); +INSERT INTO t1 VALUES ( 1, 5 ), ( 2, 4 ), ( 3, 3 ), ( 4, 2 ), ( 5, 1 ); +SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c; +SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c DESC; + +CREATE TABLE t2 ( a INT, b INT, c DECIMAL(5, 4) ); + +INSERT INTO t2 VALUES ( 0, 1, 1.2345 ), ( 1, 2, 1.2345 ), + ( 3, 3, 1.2345 ), ( 2, 4, 1.2345 ); + +SELECT a, b, MAX(ROUND(c, a)) +FROM t2 +GROUP BY a, b +ORDER BY b; + +SELECT a, b, ROUND(c, a) +FROM t2; + +CREATE TABLE t3( a INT, b DECIMAL(6, 3) ); +INSERT INTO t3 VALUES( 0, 1.5 ); +SELECT ROUND( b, a ) FROM t3; + +CREATE TABLE t4( a INT, b DECIMAL( 12, 0) ); +INSERT INTO t4 VALUES( -9, 1.5e9 ); +SELECT ROUND( b, a ) FROM t4; + +CREATE TABLE t5( a INT, b DECIMAL( 13, 12 ) ); +INSERT INTO t5 VALUES( 0, 1.5 ); +INSERT INTO t5 VALUES( 9, 1.5e-9 ); +SELECT ROUND( b, a ) FROM t5; + +CREATE TABLE t6( a INT ); +INSERT INTO t6 VALUES( 6 / 8 ); +SELECT * FROM t6; + +SELECT ROUND(20061108085411.000002); + +DROP TABLE t1, t2, t3, t4, t5, t6; + --echo End of 5.0 tests diff --git a/mysql-test/t/udf_skip_grants-master.opt b/mysql-test/t/udf_skip_grants-master.opt new file mode 100644 index 00000000000..5699a3387b8 --- /dev/null +++ b/mysql-test/t/udf_skip_grants-master.opt @@ -0,0 +1 @@ +--skip-grant-tables diff --git a/mysql-test/t/udf_skip_grants.test b/mysql-test/t/udf_skip_grants.test new file mode 100644 index 00000000000..bd9402e0d8a --- /dev/null +++ b/mysql-test/t/udf_skip_grants.test @@ -0,0 +1,28 @@ +####################### udf_skip_grants.test ########################### +# # +# Test for bug #32020 "loading udfs while --skip-grant-tables is # +# enabled causes out of memory errors" # +# # +# Creation: # +# 2007-12-24 akopytov Moved the test case for bug #32020 from # +# skip_grants.test to a separate test to ensure # +# that it is only run when the server is built # +# with support for dynamically loaded libraries # +# (see bug #33305). # +# # +######################################################################## + +-- source include/not_embedded.inc +-- source include/have_udf.inc + +# +# Bug #32020: loading udfs while --skip-grant-tables is enabled causes out of +# memory errors +# + +--error ER_CANT_INITIALIZE_UDF +CREATE FUNCTION a RETURNS STRING SONAME ''; +--error ER_SP_DOES_NOT_EXIST +DROP FUNCTION a; + +--echo End of 5.0 tests diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index a57ab469ac2..70789404d6e 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -922,4 +922,70 @@ DROP TABLE t1; select @var; --error 1172 (select 2) union (select 1 into @var); + +# +# Bug#27848: order-by of union clashes with rollup of select part +# + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (10), (20); +CREATE TABLE t2 (b int); +INSERT INTO t2 VALUES (10), (50), (50); + +SELECT a,1 FROM t1 +UNION +SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP +ORDER BY a; + +SELECT a,1 FROM t1 +UNION +SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP +ORDER BY a DESC; + +SELECT a,1 FROM t1 +UNION +SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP +ORDER BY a ASC LIMIT 3; + +SELECT a,1 FROM t1 +UNION ALL +SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP +ORDER BY a DESC; + +--error ER_WRONG_USAGE +SELECT a,1 FROM t1 +UNION +(SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP ORDER BY a); + +--error ER_WRONG_USAGE +SELECT a,1 FROM t1 +UNION ALL +SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP ORDER BY a +UNION +SELECT 1,1; + +DROP TABLE t1,t2; + +# Bug#32848: Data type conversion bug in union subselects in MySQL 5.0.38 +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1), (2), (3); + +CREATE TABLE t2 SELECT * FROM (SELECT NULL) a UNION SELECT a FROM t1; +DESC t2; + +CREATE TABLE t3 SELECT a FROM t1 UNION SELECT * FROM (SELECT NULL) a; +DESC t3; + +CREATE TABLE t4 SELECT NULL; +DESC t4; + +CREATE TABLE t5 SELECT NULL UNION SELECT NULL; +DESC t5; + +CREATE TABLE t6 +SELECT * FROM (SELECT * FROM (SELECT NULL)a) b UNION SELECT a FROM t1; +DESC t6; + +DROP TABLE t1, t2, t3, t4, t5, t6; --echo End of 5.0 tests diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 7f769c50449..58ef9c1eff1 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3453,6 +3453,20 @@ DROP VIEW v2; DROP VIEW v3; DROP TABLE t1; +--echo # +--echo # Bug#29477: Not all fields of the target table were checked to have +--echo # a default value when inserting into a view. +--echo # +create table t1(f1 int, f2 int not null); +create view v1 as select f1 from t1; +insert into v1 values(1); +set @old_mode=@@sql_mode; +set @@sql_mode=traditional; +--error ER_NO_DEFAULT_FOR_VIEW_FIELD +insert into v1 values(1); +set @@sql_mode=@old_mode; +drop view v1; +drop table t1; --echo End of 5.0 tests. diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test index b5bae109f5f..d0eaaf1a764 100644 --- a/mysql-test/t/warnings.test +++ b/mysql-test/t/warnings.test @@ -65,6 +65,7 @@ create table t1(a tinyint NOT NULL, b tinyint unsigned, c char(5)); insert into t1 values(NULL,100,'mysql'),(10,-1,'mysql ab'),(500,256,'open source'),(20,NULL,'test'); alter table t1 modify c char(4); alter table t1 add d char(2); +--error 1048 update t1 set a=NULL where a=10; update t1 set c='mysql ab' where c='test'; update t1 set d=c; diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c index a31b9595c85..63525e4d927 100644 --- a/mysys/mf_pack.c +++ b/mysys/mf_pack.c @@ -282,7 +282,7 @@ void symdirget(char *dir) SYNOPSIS unpack_dirname() - to Store result here. May be = from + to result-buffer, FN_REFLEN characters. may be == from from 'Packed' directory name (may contain ~) IMPLEMENTATION @@ -408,7 +408,7 @@ size_t unpack_filename(char * to, const char *from) /* Convert filename (unix standard) to system standard */ /* Used before system command's like open(), create() .. */ - /* Returns length of to */ + /* Returns used length of to; total length should be FN_REFLEN */ size_t system_filename(char * to, const char *from) { diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index 8d3e2133a45..a5deb52d526 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -396,6 +396,7 @@ copyfileto $BASE/mysql-test \ $CP mysql-test/lib/*.pl $BASE/mysql-test/lib $CP mysql-test/t/*.def $BASE/mysql-test/t $CP mysql-test/include/*.inc $BASE/mysql-test/include +$CP mysql-test/include/*.sql $BASE/mysql-test/include $CP mysql-test/include/*.test $BASE/mysql-test/include $CP mysql-test/t/*.def $BASE/mysql-test/t $CP mysql-test/std_data/*.dat mysql-test/std_data/*.frm \ diff --git a/sql-common/client.c b/sql-common/client.c index 1a0f9c64d7d..a26207038cf 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -2100,7 +2100,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, /* Check if version of protocol matches current one */ mysql->protocol_version= net->read_pos[0]; - DBUG_DUMP("packet",(char*) net->read_pos,10); + DBUG_DUMP("packet",(uchar*) net->read_pos,10); DBUG_PRINT("info",("mysql protocol version %d, server=%d", PROTOCOL_VERSION, mysql->protocol_version)); if (mysql->protocol_version != PROTOCOL_VERSION) @@ -2226,7 +2226,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, Send client_flag, max_packet_size - unencrypted otherwise the server does not know we want to do SSL */ - if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net)) + if (my_net_write(net, (uchar*) buff, (uint) (end-buff)) || net_flush(net)) { set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate, ER(CR_SERVER_LOST_EXTENDED), diff --git a/sql/field.cc b/sql/field.cc index 16217e69de9..7c4f6c9ff5f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1308,7 +1308,8 @@ Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, field_name(field_name_arg), key_start(0), part_of_key(0), part_of_key_not_clustered(0), part_of_sortkey(0), unireg_check(unireg_check_arg), - field_length(length_arg), null_bit(null_bit_arg) + field_length(length_arg), null_bit(null_bit_arg), + is_created_from_null_item(FALSE) { flags=null_ptr ? 0: NOT_NULL_FLAG; comment.str= (char*) ""; @@ -5633,6 +5634,13 @@ String *Field_date::val_str(String *val_buffer, } +bool Field_date::get_time(MYSQL_TIME *ltime) +{ + bzero((char *)ltime, sizeof(MYSQL_TIME)); + return 0; +} + + int Field_date::cmp(const uchar *a_ptr, const uchar *b_ptr) { int32 a,b; diff --git a/sql/field.h b/sql/field.h index 53788560e68..e03131a10e3 100644 --- a/sql/field.h +++ b/sql/field.h @@ -90,6 +90,16 @@ public: uint32 flags; uint16 field_index; // field number in fields array uchar null_bit; // Bit used to test null bit + /** + If true, this field was created in create_tmp_field_from_item from a NULL + value. This means that the type of the field is just a guess, and the type + may be freely coerced to another type. + + @see create_tmp_field_from_item + @see Item_type_holder::get_real_type + + */ + bool is_created_from_null_item; Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, @@ -1240,6 +1250,7 @@ public: double val_real(void); longlong val_int(void); String *val_str(String*,String *); + bool get_time(MYSQL_TIME *ltime); bool send_binary(Protocol *protocol); int cmp(const uchar *,const uchar *); void sort_string(uchar *buff,uint length); @@ -1258,6 +1269,10 @@ public: :Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, cs) {} + Field_newdate(bool maybe_null_arg, const char *field_name_arg, + CHARSET_INFO *cs) + :Field_str((uchar*) 0,10, maybe_null_arg ? (uchar*) "": 0,0, + NONE, field_name_arg, cs) {} enum_field_types type() const { return MYSQL_TYPE_DATE;} enum_field_types real_type() const { return MYSQL_TYPE_NEWDATE; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; } diff --git a/sql/filesort.cc b/sql/filesort.cc index 1c1a3b8d9a3..12cc76b5852 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -41,7 +41,8 @@ if (my_b_write((file),(uchar*) (from),param->ref_length)) \ static char **make_char_array(char **old_pos, register uint fields, uint length, myf my_flag); -static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffer_file, uint count); +static uchar *read_buffpek_from_file(IO_CACHE *buffer_file, uint count, + uchar *buf); static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select, uchar * *sort_keys, IO_CACHE *buffer_file, IO_CACHE *tempfile,IO_CACHE *indexfile); @@ -246,9 +247,14 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, } else { - if (!table_sort.buffpek && table_sort.buffpek_len < maxbuffer && - !(table_sort.buffpek= - (uchar *) read_buffpek_from_file(&buffpek_pointers, maxbuffer))) + if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer) + { + x_free(table_sort.buffpek); + table_sort.buffpek= 0; + } + if (!(table_sort.buffpek= + (uchar *) read_buffpek_from_file(&buffpek_pointers, maxbuffer, + table_sort.buffpek))) goto err; buffpek= (BUFFPEK *) table_sort.buffpek; table_sort.buffpek_len= maxbuffer; @@ -376,14 +382,16 @@ static char **make_char_array(char **old_pos, register uint fields, /** Read 'count' number of buffer pointers into memory. */ -static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count) +static uchar *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count, + uchar *buf) { - ulong length; - BUFFPEK *tmp; + ulong length= sizeof(BUFFPEK)*count; + uchar *tmp= buf; DBUG_ENTER("read_buffpek_from_file"); if (count > UINT_MAX/sizeof(BUFFPEK)) return 0; /* sizeof(BUFFPEK)*count will overflow */ - tmp=(BUFFPEK*) my_malloc(length=sizeof(BUFFPEK)*count, MYF(MY_WME)); + if (!tmp) + tmp= (uchar *)my_malloc(length, MYF(MY_WME)); if (tmp) { if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) || diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index 07b0d907229..841dce2d832 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -799,7 +799,7 @@ static int ndbcluster_create_ndb_apply_status_table(THD *thd) " log_name VARCHAR(255) BINARY NOT NULL, " " start_pos BIGINT UNSIGNED NOT NULL, " " end_pos BIGINT UNSIGNED NOT NULL, " - " PRIMARY KEY USING HASH (server_id) ) ENGINE=NDB"); + " PRIMARY KEY USING HASH (server_id) ) ENGINE=NDB CHARACTER SET latin1"); const int no_print_error[5]= {ER_TABLE_EXISTS_ERROR, 701, @@ -860,7 +860,7 @@ static int ndbcluster_create_schema_table(THD *thd) " id INT UNSIGNED NOT NULL," " version INT UNSIGNED NOT NULL," " type INT UNSIGNED NOT NULL," - " PRIMARY KEY USING HASH (db,name) ) ENGINE=NDB"); + " PRIMARY KEY USING HASH (db,name) ) ENGINE=NDB CHARACTER SET latin1"); const int no_print_error[5]= {ER_TABLE_EXISTS_ERROR, 701, @@ -4036,6 +4036,7 @@ restart: i_ndb->setReportThreshEventFreeMem(ndb_report_thresh_binlog_mem_usage); bzero((char*) &row, sizeof(row)); + thd->variables.character_set_client= &my_charset_latin1; injector::transaction trans; // pass table map before epoch { diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index bd0004f92cb..a74322acee1 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -367,7 +367,7 @@ bool ha_partition::initialise_partition(MEM_ROOT *mem_root) HA_CAN_GEOMETRY, HA_CAN_FULLTEXT, HA_CAN_SQL_HANDLER, HA_DUPLICATE_POS, HA_CAN_INSERT_DELAYED is disabled until further investigated. */ - m_table_flags= (ulong)m_file[0]->table_flags(); + m_table_flags= (ulong)m_file[0]->ha_table_flags(); m_low_byte_first= m_file[0]->low_byte_first(); m_pkey_is_clustered= TRUE; file_array= m_file; @@ -382,7 +382,7 @@ bool ha_partition::initialise_partition(MEM_ROOT *mem_root) } if (!file->primary_key_is_clustered()) m_pkey_is_clustered= FALSE; - m_table_flags&= file->table_flags(); + m_table_flags&= file->ha_table_flags(); } while (*(++file_array)); m_table_flags&= ~(HA_CAN_GEOMETRY | HA_CAN_FULLTEXT | HA_DUPLICATE_POS | HA_CAN_SQL_HANDLER | HA_CAN_INSERT_DELAYED | @@ -616,7 +616,7 @@ int ha_partition::drop_partitions(const char *path) sub_elem->partition_name, name_variant); file= m_file[part]; DBUG_PRINT("info", ("Drop subpartition %s", part_name_buff)); - if ((ret_error= file->delete_table((const char *) part_name_buff))) + if ((ret_error= file->ha_delete_table(part_name_buff))) error= ret_error; if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos)) error= 1; @@ -629,7 +629,7 @@ int ha_partition::drop_partitions(const char *path) TRUE); file= m_file[i]; DBUG_PRINT("info", ("Drop partition %s", part_name_buff)); - if ((ret_error= file->delete_table((const char *) part_name_buff))) + if ((ret_error= file->ha_delete_table(part_name_buff))) error= ret_error; if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos)) error= 1; @@ -707,7 +707,7 @@ int ha_partition::rename_partitions(const char *path) sub_elem->partition_name, NORMAL_PART_NAME); DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); - if ((ret_error= file->delete_table((const char *) norm_name_buff))) + if ((ret_error= file->ha_delete_table(norm_name_buff))) error= ret_error; else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos)) error= 1; @@ -722,7 +722,7 @@ int ha_partition::rename_partitions(const char *path) part_elem->partition_name, NORMAL_PART_NAME, TRUE); DBUG_PRINT("info", ("Delete partition %s", norm_name_buff)); - if ((ret_error= file->delete_table((const char *) norm_name_buff))) + if ((ret_error= file->ha_delete_table(norm_name_buff))) error= ret_error; else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos)) error= 1; @@ -778,7 +778,7 @@ int ha_partition::rename_partitions(const char *path) { file= m_reorged_file[part_count++]; DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); - if ((ret_error= file->delete_table((const char *) norm_name_buff))) + if ((ret_error= file->ha_delete_table(norm_name_buff))) error= ret_error; else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos)) error= 1; @@ -791,8 +791,8 @@ int ha_partition::rename_partitions(const char *path) TEMP_PART_NAME); DBUG_PRINT("info", ("Rename subpartition from %s to %s", part_name_buff, norm_name_buff)); - if ((ret_error= file->rename_table((const char *) part_name_buff, - (const char *) norm_name_buff))) + if ((ret_error= file->ha_rename_table(part_name_buff, + norm_name_buff))) error= ret_error; else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos)) error= 1; @@ -809,7 +809,7 @@ int ha_partition::rename_partitions(const char *path) { file= m_reorged_file[part_count++]; DBUG_PRINT("info", ("Delete partition %s", norm_name_buff)); - if ((ret_error= file->delete_table((const char *) norm_name_buff))) + if ((ret_error= file->ha_delete_table(norm_name_buff))) error= ret_error; else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos)) error= 1; @@ -821,8 +821,8 @@ int ha_partition::rename_partitions(const char *path) TRUE); DBUG_PRINT("info", ("Rename partition from %s to %s", part_name_buff, norm_name_buff)); - if ((ret_error= file->rename_table((const char *) part_name_buff, - (const char *) norm_name_buff))) + if ((ret_error= file->ha_rename_table(part_name_buff, + norm_name_buff))) error= ret_error; else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos)) error= 1; @@ -1036,9 +1036,9 @@ static int handle_opt_part(THD *thd, HA_CHECK_OPT *check_opt, DBUG_PRINT("enter", ("flag = %u", flag)); if (flag == OPTIMIZE_PARTS) - error= file->optimize(thd, check_opt); + error= file->ha_optimize(thd, check_opt); else if (flag == ANALYZE_PARTS) - error= file->analyze(thd, check_opt); + error= file->ha_analyze(thd, check_opt); else if (flag == CHECK_PARTS) error= file->ha_check(thd, check_opt); else if (flag == REPAIR_PARTS) @@ -1139,7 +1139,7 @@ int ha_partition::prepare_new_partition(TABLE *tbl, if ((error= set_up_table_before_create(tbl, part_name, create_info, 0, p_elem))) goto error; - if ((error= file->create(part_name, tbl, create_info))) + if ((error= file->ha_create(part_name, tbl, create_info))) goto error; create_flag= TRUE; if ((error= file->ha_open(tbl, part_name, m_mode, m_open_test_lock))) @@ -1150,13 +1150,13 @@ int ha_partition::prepare_new_partition(TABLE *tbl, assumes that external_lock() is last call that may fail here. Otherwise see description for cleanup_new_partition(). */ - if ((error= file->external_lock(current_thd, m_lock_type))) + if ((error= file->ha_external_lock(current_thd, m_lock_type))) goto error; DBUG_RETURN(0); error: if (create_flag) - VOID(file->delete_table(part_name)); + VOID(file->ha_delete_table(part_name)); DBUG_RETURN(error); } @@ -1574,14 +1574,18 @@ int ha_partition::copy_partitions(ulonglong *copied, ulonglong *deleted) } else { + THD *thd= ha_thd(); /* Copy record to new handler */ copied++; - if ((result= m_new_file[new_part]->write_row(m_rec0))) + tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */ + result= m_new_file[new_part]->ha_write_row(m_rec0); + reenable_binlog(thd); + if (result) goto error; } } late_extra_no_cache(reorg_part); - file->rnd_end(); + file->ha_rnd_end(); reorg_part++; } DBUG_RETURN(FALSE); @@ -1698,16 +1702,15 @@ uint ha_partition::del_ren_cre_table(const char *from, { // Rename branch create_partition_name(to_buff, to, name_buffer_ptr, NORMAL_PART_NAME, FALSE); - error= (*file)->rename_table((const char*) from_buff, - (const char*) to_buff); + error= (*file)->ha_rename_table(from_buff, to_buff); } else if (table_arg == NULL) // delete branch - error= (*file)->delete_table((const char*) from_buff); + error= (*file)->ha_delete_table(from_buff); else { if ((error= set_up_table_before_create(table_arg, from_buff, create_info, i, NULL)) || - ((error= (*file)->create(from_buff, table_arg, create_info)))) + ((error= (*file)->ha_create(from_buff, table_arg, create_info)))) goto create_error; } name_buffer_ptr= strend(name_buffer_ptr) + 1; @@ -1722,7 +1725,7 @@ create_error: { create_partition_name(from_buff, from, name_buffer_ptr, NORMAL_PART_NAME, FALSE); - VOID((*file)->delete_table((const char*) from_buff)); + VOID((*file)->ha_delete_table((const char*) from_buff)); name_buffer_ptr= strend(name_buffer_ptr) + 1; } DBUG_RETURN(error); @@ -2314,7 +2317,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) } /* Recalculate table flags as they may change after open */ - m_table_flags= m_file[0]->table_flags(); + m_table_flags= m_file[0]->ha_table_flags(); file= m_file; do { @@ -2326,7 +2329,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) m_no_locks+= (*file)->lock_count(); name_buffer_ptr+= strlen(name_buffer_ptr) + 1; set_if_bigger(ref_length, ((*file)->ref_length)); - m_table_flags&= (*file)->table_flags(); + m_table_flags&= (*file)->ha_table_flags(); } while (*(++file)); m_table_flags&= ~(HA_CAN_GEOMETRY | HA_CAN_FULLTEXT | HA_DUPLICATE_POS | HA_CAN_SQL_HANDLER | HA_CAN_INSERT_DELAYED); @@ -2482,7 +2485,7 @@ repeat: { DBUG_PRINT("info", ("external_lock(thd, %d) iteration %d", lock_type, (int) (file - m_file))); - if ((error= (*file)->external_lock(thd, lock_type))) + if ((error= (*file)->ha_external_lock(thd, lock_type))) { if (F_UNLCK != lock_type) goto err_handler; @@ -2501,7 +2504,7 @@ repeat: err_handler: while (file-- != m_file) { - (*file)->external_lock(thd, F_UNLCK); + (*file)->ha_external_lock(thd, F_UNLCK); } DBUG_RETURN(error); } @@ -2694,6 +2697,7 @@ int ha_partition::write_row(uchar * buf) longlong func_value; bool autoincrement_lock= FALSE; my_bitmap_map *old_map; + THD *thd= ha_thd(); #ifdef NOT_NEEDED uchar *rec0= m_rec0; #endif @@ -2765,7 +2769,9 @@ int ha_partition::write_row(uchar * buf) } m_last_part= part_id; DBUG_PRINT("info", ("Insert in partition %d", part_id)); - error= m_file[part_id]->write_row(buf); + tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */ + error= m_file[part_id]->ha_write_row(buf); + reenable_binlog(thd); exit: if (autoincrement_lock) pthread_mutex_unlock(&table_share->mutex); @@ -2806,6 +2812,7 @@ exit: int ha_partition::update_row(const uchar *old_data, uchar *new_data) { + THD *thd= ha_thd(); uint32 new_part_id, old_part_id; int error= 0; longlong func_value; @@ -2840,16 +2847,25 @@ int ha_partition::update_row(const uchar *old_data, uchar *new_data) if (new_part_id == old_part_id) { DBUG_PRINT("info", ("Update in partition %d", new_part_id)); - error= m_file[new_part_id]->update_row(old_data, new_data); + tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */ + error= m_file[new_part_id]->ha_update_row(old_data, new_data); + reenable_binlog(thd); goto exit; } else { DBUG_PRINT("info", ("Update from partition %d to partition %d", old_part_id, new_part_id)); - if ((error= m_file[new_part_id]->write_row(new_data))) + tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */ + error= m_file[new_part_id]->ha_write_row(new_data); + reenable_binlog(thd); + if (error) goto exit; - if ((error= m_file[old_part_id]->delete_row(old_data))) + + tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */ + error= m_file[old_part_id]->ha_delete_row(old_data); + reenable_binlog(thd); + if (error) { #ifdef IN_THE_FUTURE (void) m_file[new_part_id]->delete_last_inserted_row(new_data); @@ -2896,6 +2912,7 @@ int ha_partition::delete_row(const uchar *buf) { uint32 part_id; int error; + THD *thd= ha_thd(); DBUG_ENTER("ha_partition::delete_row"); if ((error= get_part_for_delete(buf, m_rec0, m_part_info, &part_id))) @@ -2903,7 +2920,10 @@ int ha_partition::delete_row(const uchar *buf) DBUG_RETURN(error); } m_last_part= part_id; - DBUG_RETURN(m_file[part_id]->delete_row(buf)); + tmp_disable_binlog(thd); + error= m_file[part_id]->ha_delete_row(buf); + reenable_binlog(thd); + DBUG_RETURN(error); } @@ -2938,7 +2958,7 @@ int ha_partition::delete_all_rows() file= m_file; do { - if ((error= (*file)->delete_all_rows())) + if ((error= (*file)->ha_delete_all_rows())) DBUG_RETURN(error); } while (*(++file)); DBUG_RETURN(0); @@ -3980,7 +4000,7 @@ int ha_partition::partition_scan_set_up(uchar * buf, bool idx_read_flag) int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same) { - handler *file= file= m_file[m_part_spec.start_part]; + handler *file= m_file[m_part_spec.start_part]; int error; DBUG_ENTER("ha_partition::handle_unordered_next"); @@ -3999,7 +4019,7 @@ int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same) } else if (!(error= file->index_next(buf))) { - if (!(file->table_flags() & HA_READ_ORDER) || + if (!(file->ha_table_flags() & HA_READ_ORDER) || compare_key(end_range) <= 0) { m_last_part= m_part_spec.start_part; @@ -4077,7 +4097,7 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf) } if (!error) { - if (!(file->table_flags() & HA_READ_ORDER) || + if (!(file->ha_table_flags() & HA_READ_ORDER) || compare_key(end_range) <= 0) { m_last_part= i; @@ -5003,7 +5023,7 @@ int ha_partition::reset(void) file= m_file; do { - if ((tmp= (*file)->reset())) + if ((tmp= (*file)->ha_reset())) result= tmp; } while (*(++file)); DBUG_RETURN(result); @@ -5645,7 +5665,7 @@ void ha_partition::release_auto_increment() for (uint i= 0; i < m_tot_parts; i++) { - m_file[i]->release_auto_increment(); + m_file[i]->ha_release_auto_increment(); } DBUG_VOID_RETURN; } @@ -5681,7 +5701,7 @@ int ha_partition::disable_indexes(uint mode) for (file= m_file; *file; file++) { - if ((error= (*file)->disable_indexes(mode))) + if ((error= (*file)->ha_disable_indexes(mode))) break; } return error; @@ -5705,7 +5725,7 @@ int ha_partition::enable_indexes(uint mode) for (file= m_file; *file; file++) { - if ((error= (*file)->enable_indexes(mode))) + if ((error= (*file)->ha_enable_indexes(mode))) break; } return error; diff --git a/sql/handler.cc b/sql/handler.cc index 6489041eaf1..421708e5958 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1477,7 +1477,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, DBUG_RETURN(ENOENT); path= check_lowercase_names(file, path, tmp_path); - if ((error= file->delete_table(path)) && generate_warning) + if ((error= file->ha_delete_table(path)) && generate_warning) { /* Because file->print_error() use my_error() to generate the error message @@ -1496,8 +1496,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, dummy_share.table_name.length= strlen(alias); dummy_table.alias= alias; - file->table_share= &dummy_share; - file->table= &dummy_table; + file->change_table_ptr(&dummy_table, &dummy_share); thd->push_internal_handler(&ha_delete_table_error_handler); file->print_error(error, 0); @@ -2506,6 +2505,12 @@ int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt) } +/** + Repair table: public interface. + + @sa handler::repair() +*/ + int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt) { int result; @@ -2516,6 +2521,328 @@ int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt) /** + Bulk update row: public interface. + + @sa handler::bulk_update_row() +*/ + +int +handler::ha_bulk_update_row(const uchar *old_data, uchar *new_data, + uint *dup_key_found) +{ + return bulk_update_row(old_data, new_data, dup_key_found); +} + + +/** + Delete all rows: public interface. + + @sa handler::delete_all_rows() +*/ + +int +handler::ha_delete_all_rows() +{ + return delete_all_rows(); +} + + +/** + Reset auto increment: public interface. + + @sa handler::reset_auto_increment() +*/ + +int +handler::ha_reset_auto_increment(ulonglong value) +{ + return reset_auto_increment(value); +} + + +/** + Backup table: public interface. + + @sa handler::backup() +*/ + +int +handler::ha_backup(THD* thd, HA_CHECK_OPT* check_opt) +{ + return backup(thd, check_opt); +} + + +/** + Restore table: public interface. + + @sa handler::restore() +*/ + +int +handler::ha_restore(THD* thd, HA_CHECK_OPT* check_opt) +{ + return restore(thd, check_opt); +} + + +/** + Optimize table: public interface. + + @sa handler::optimize() +*/ + +int +handler::ha_optimize(THD* thd, HA_CHECK_OPT* check_opt) +{ + return optimize(thd, check_opt); +} + + +/** + Analyze table: public interface. + + @sa handler::analyze() +*/ + +int +handler::ha_analyze(THD* thd, HA_CHECK_OPT* check_opt) +{ + return analyze(thd, check_opt); +} + + +/** + Check and repair table: public interface. + + @sa handler::check_and_repair() +*/ + +bool +handler::ha_check_and_repair(THD *thd) +{ + return check_and_repair(thd); +} + + +/** + Disable indexes: public interface. + + @sa handler::disable_indexes() +*/ + +int +handler::ha_disable_indexes(uint mode) +{ + return disable_indexes(mode); +} + + +/** + Enable indexes: public interface. + + @sa handler::enable_indexes() +*/ + +int +handler::ha_enable_indexes(uint mode) +{ + return enable_indexes(mode); +} + + +/** + Discard or import tablespace: public interface. + + @sa handler::discard_or_import_tablespace() +*/ + +int +handler::ha_discard_or_import_tablespace(my_bool discard) +{ + return discard_or_import_tablespace(discard); +} + + +/** + Prepare for alter: public interface. + + Called to prepare an *online* ALTER. + + @sa handler::prepare_for_alter() +*/ + +void +handler::ha_prepare_for_alter() +{ + prepare_for_alter(); +} + + +/** + Rename table: public interface. + + @sa handler::rename_table() +*/ + +int +handler::ha_rename_table(const char *from, const char *to) +{ + return rename_table(from, to); +} + + +/** + Delete table: public interface. + + @sa handler::delete_table() +*/ + +int +handler::ha_delete_table(const char *name) +{ + return delete_table(name); +} + + +/** + Drop table in the engine: public interface. + + @sa handler::drop_table() +*/ + +void +handler::ha_drop_table(const char *name) +{ + return drop_table(name); +} + + +/** + Create a table in the engine: public interface. + + @sa handler::create() +*/ + +int +handler::ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info) +{ + return create(name, form, info); +} + + +/** + Create handler files for CREATE TABLE: public interface. + + @sa handler::create_handler_files() +*/ + +int +handler::ha_create_handler_files(const char *name, const char *old_name, + int action_flag, HA_CREATE_INFO *info) +{ + return create_handler_files(name, old_name, action_flag, info); +} + + +/** + Change partitions: public interface. + + @sa handler::change_partitions() +*/ + +int +handler::ha_change_partitions(HA_CREATE_INFO *create_info, + const char *path, + ulonglong *copied, + ulonglong *deleted, + const uchar *pack_frm_data, + size_t pack_frm_len) +{ + return change_partitions(create_info, path, copied, deleted, + pack_frm_data, pack_frm_len); +} + + +/** + Drop partitions: public interface. + + @sa handler::drop_partitions() +*/ + +int +handler::ha_drop_partitions(const char *path) +{ + return drop_partitions(path); +} + + +/** + Rename partitions: public interface. + + @sa handler::rename_partitions() +*/ + +int +handler::ha_rename_partitions(const char *path) +{ + return rename_partitions(path); +} + + +/** + Optimize partitions: public interface. + + @sa handler::optimize_partitions() +*/ + +int +handler::ha_optimize_partitions(THD *thd) +{ + return optimize_partitions(thd); +} + + +/** + Analyze partitions: public interface. + + @sa handler::analyze_partitions() +*/ + +int +handler::ha_analyze_partitions(THD *thd) +{ + return analyze_partitions(thd); +} + + +/** + Check partitions: public interface. + + @sa handler::check_partitions() +*/ + +int +handler::ha_check_partitions(THD *thd) +{ + return check_partitions(thd); +} + + +/** + Repair partitions: public interface. + + @sa handler::repair_partitions() +*/ + +int +handler::ha_repair_partitions(THD *thd) +{ + return repair_partitions(thd); +} + + +/** Tell the storage engine that it is allowed to "disable transaction" in the handler. It is a hint that ACID is not required - it is used in NDB for ALTER TABLE, for example, when data are copied to temporary table. @@ -2655,7 +2982,7 @@ int ha_create_table(THD *thd, const char *path, name= check_lowercase_names(table.file, share.path.str, name_buff); - error= table.file->create(name, &table, create_info); + error= table.file->ha_create(name, &table, create_info); VOID(closefrm(&table, 0)); if (error) { @@ -2726,7 +3053,7 @@ int ha_create_table_from_engine(THD* thd, const char *db, const char *name) create_info.table_options|= HA_OPTION_CREATE_FROM_ENGINE; check_lowercase_names(table.file, path, path); - error=table.file->create(path,&table,&create_info); + error=table.file->ha_create(path, &table, &create_info); VOID(closefrm(&table, 1)); DBUG_RETURN(error != 0); diff --git a/sql/handler.h b/sql/handler.h index 75c56e8339e..8e3073eb6ba 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -967,10 +967,6 @@ uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map); class handler :public Sql_alloc { - friend class ha_partition; - friend int ha_delete_table(THD*,handlerton*,const char*,const char*, - const char*,bool); - public: typedef ulonglong Table_flags; protected: @@ -1118,6 +1114,40 @@ public: estimation_rows_to_insert= 0; return end_bulk_insert(); } + int ha_bulk_update_row(const uchar *old_data, uchar *new_data, + uint *dup_key_found); + int ha_delete_all_rows(); + int ha_reset_auto_increment(ulonglong value); + int ha_backup(THD* thd, HA_CHECK_OPT* check_opt); + int ha_restore(THD* thd, HA_CHECK_OPT* check_opt); + int ha_optimize(THD* thd, HA_CHECK_OPT* check_opt); + int ha_analyze(THD* thd, HA_CHECK_OPT* check_opt); + bool ha_check_and_repair(THD *thd); + int ha_disable_indexes(uint mode); + int ha_enable_indexes(uint mode); + int ha_discard_or_import_tablespace(my_bool discard); + void ha_prepare_for_alter(); + int ha_rename_table(const char *from, const char *to); + int ha_delete_table(const char *name); + void ha_drop_table(const char *name); + + int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info); + + int ha_create_handler_files(const char *name, const char *old_name, + int action_flag, HA_CREATE_INFO *info); + + int ha_change_partitions(HA_CREATE_INFO *create_info, + const char *path, + ulonglong *copied, + ulonglong *deleted, + const uchar *pack_frm_data, + size_t pack_frm_len); + int ha_drop_partitions(const char *path); + int ha_rename_partitions(const char *path); + int ha_optimize_partitions(THD *thd); + int ha_analyze_partitions(THD *thd); + int ha_check_partitions(THD *thd); + int ha_repair_partitions(THD *thd); void adjust_next_insert_id_after_explicit_value(ulonglong nr); int update_auto_increment(); @@ -1204,25 +1234,6 @@ public: */ virtual bool start_bulk_delete() { return 1; } /** - This method is similar to update_row, however the handler doesn't need - to execute the updates at this point in time. The handler can be certain - that another call to bulk_update_row will occur OR a call to - exec_bulk_update before the set of updates in this query is concluded. - - @param old_data Old record - @param new_data New record - @param dup_key_found Number of duplicate keys found - - @retval 0 Bulk delete used by handler - @retval 1 Bulk delete not used, normal operation used - */ - virtual int bulk_update_row(const uchar *old_data, uchar *new_data, - uint *dup_key_found) - { - DBUG_ASSERT(FALSE); - return HA_ERR_WRONG_COMMAND; - } - /** After this call all outstanding updates must be performed. The number of duplicate key errors are reported in the duplicate key parameter. It is allowed to continue to the batched update after this call, the @@ -1369,14 +1380,6 @@ public: virtual void try_semi_consistent_read(bool) {} virtual void unlock_row() {} virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;} - /** - This is called to delete all rows in a table - If the handler don't support this, then this function will - return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one - by one. - */ - virtual int delete_all_rows() - { return (my_errno=HA_ERR_WRONG_COMMAND); } virtual void get_auto_increment(ulonglong offset, ulonglong increment, ulonglong nb_desired_values, ulonglong *first_value, @@ -1401,42 +1404,17 @@ public: next_insert_id= (prev_insert_id > 0) ? prev_insert_id : insert_id_for_cur_row; } - /** - Reset the auto-increment counter to the given value, i.e. the next row - inserted will get the given value. This is called e.g. after TRUNCATE - is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is - returned by storage engines that don't support this operation. - */ - virtual int reset_auto_increment(ulonglong value) - { return HA_ERR_WRONG_COMMAND; } virtual void update_create_info(HA_CREATE_INFO *create_info) {} int check_old_types(); - virtual int backup(THD* thd, HA_CHECK_OPT* check_opt) - { return HA_ADMIN_NOT_IMPLEMENTED; } - /** - Restore assumes .frm file must exist, and that generate_table() has been - called; It will just copy the data file and run repair. - */ - virtual int restore(THD* thd, HA_CHECK_OPT* check_opt) - { return HA_ADMIN_NOT_IMPLEMENTED; } - virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt) - { return HA_ADMIN_NOT_IMPLEMENTED; } - virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt) - { return HA_ADMIN_NOT_IMPLEMENTED; } virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt) { return HA_ADMIN_NOT_IMPLEMENTED; } virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt) { return HA_ADMIN_NOT_IMPLEMENTED; } /* end of the list of admin commands */ - virtual bool check_and_repair(THD *thd) { return HA_ERR_WRONG_COMMAND; } virtual int dump(THD* thd, int fd = -1) { return HA_ERR_WRONG_COMMAND; } - virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; } - virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; } virtual int indexes_are_disabled(void) {return 0;} - virtual int discard_or_import_tablespace(my_bool discard) - {return HA_ERR_WRONG_COMMAND;} virtual int net_read_dump(NET* net) { return HA_ERR_WRONG_COMMAND; } virtual char *update_table_comment(const char * comment) { return (char*) comment;} @@ -1494,7 +1472,6 @@ public: virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0; - virtual void prepare_for_alter() { return; } virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys) { return (HA_ERR_WRONG_COMMAND); } virtual int prepare_drop_index(TABLE *table_arg, uint *key_num, @@ -1526,46 +1503,11 @@ public: virtual bool is_crashed() const { return 0; } virtual bool auto_repair() const { return 0; } - /** - default rename_table() and delete_table() rename/delete files with a - given name and extensions from bas_ext() - */ - virtual int rename_table(const char *from, const char *to); - virtual int delete_table(const char *name); - virtual void drop_table(const char *name); - - virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0; - #define CHF_CREATE_FLAG 0 #define CHF_DELETE_FLAG 1 #define CHF_RENAME_FLAG 2 #define CHF_INDEX_FLAG 3 - virtual int create_handler_files(const char *name, const char *old_name, - int action_flag, - HA_CREATE_INFO *create_info) - { return FALSE; } - - virtual int change_partitions(HA_CREATE_INFO *create_info, - const char *path, - ulonglong *copied, - ulonglong *deleted, - const uchar *pack_frm_data, - size_t pack_frm_len) - { return HA_ERR_WRONG_COMMAND; } - virtual int drop_partitions(const char *path) - { return HA_ERR_WRONG_COMMAND; } - virtual int rename_partitions(const char *path) - { return HA_ERR_WRONG_COMMAND; } - virtual int optimize_partitions(THD *thd) - { return HA_ERR_WRONG_COMMAND; } - virtual int analyze_partitions(THD *thd) - { return HA_ERR_WRONG_COMMAND; } - virtual int check_partitions(THD *thd) - { return HA_ERR_WRONG_COMMAND; } - virtual int repair_partitions(THD *thd) - { return HA_ERR_WRONG_COMMAND; } - /** @note lock_count() can return > 1 if the table is MERGE or partitioned. */ @@ -1680,22 +1622,6 @@ public: uint table_changes) { return COMPATIBLE_DATA_NO; } - /** These are only called from sql_select for internal temporary tables */ - virtual int write_row(uchar *buf __attribute__((unused))) - { - return HA_ERR_WRONG_COMMAND; - } - - virtual int update_row(const uchar *old_data __attribute__((unused)), - uchar *new_data __attribute__((unused))) - { - return HA_ERR_WRONG_COMMAND; - } - - virtual int delete_row(const uchar *buf __attribute__((unused))) - { - return HA_ERR_WRONG_COMMAND; - } /** use_hidden_primary_key() is called in case of an update/delete when (table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined @@ -1708,6 +1634,16 @@ protected: void ha_statistic_increment(ulong SSV::*offset) const; void **ha_data(THD *) const; THD *ha_thd(void) const; + + /** + Default rename_table() and delete_table() rename/delete files with a + given name and extensions from bas_ext(). + + These methods can be overridden, but their default implementation + provide useful functionality. + */ + virtual int rename_table(const char *from, const char *to); + virtual int delete_table(const char *name); private: /* Low-level primitives for storage engines. These should be @@ -1727,6 +1663,21 @@ private: */ virtual int rnd_init(bool scan)= 0; virtual int rnd_end() { return 0; } + virtual int write_row(uchar *buf __attribute__((unused))) + { + return HA_ERR_WRONG_COMMAND; + } + + virtual int update_row(const uchar *old_data __attribute__((unused)), + uchar *new_data __attribute__((unused))) + { + return HA_ERR_WRONG_COMMAND; + } + + virtual int delete_row(const uchar *buf __attribute__((unused))) + { + return HA_ERR_WRONG_COMMAND; + } /** Reset state of file to after 'open'. This function is called after every statement for all tables used @@ -1782,6 +1733,85 @@ private: { return HA_ERR_WRONG_COMMAND; } virtual int index_read_last(uchar * buf, const uchar * key, uint key_len) { return (my_errno= HA_ERR_WRONG_COMMAND); } + /** + This method is similar to update_row, however the handler doesn't need + to execute the updates at this point in time. The handler can be certain + that another call to bulk_update_row will occur OR a call to + exec_bulk_update before the set of updates in this query is concluded. + + @param old_data Old record + @param new_data New record + @param dup_key_found Number of duplicate keys found + + @retval 0 Bulk delete used by handler + @retval 1 Bulk delete not used, normal operation used + */ + virtual int bulk_update_row(const uchar *old_data, uchar *new_data, + uint *dup_key_found) + { + DBUG_ASSERT(FALSE); + return HA_ERR_WRONG_COMMAND; + } + /** + This is called to delete all rows in a table + If the handler don't support this, then this function will + return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one + by one. + */ + virtual int delete_all_rows() + { return (my_errno=HA_ERR_WRONG_COMMAND); } + /** + Reset the auto-increment counter to the given value, i.e. the next row + inserted will get the given value. This is called e.g. after TRUNCATE + is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is + returned by storage engines that don't support this operation. + */ + virtual int reset_auto_increment(ulonglong value) + { return HA_ERR_WRONG_COMMAND; } + virtual int backup(THD* thd, HA_CHECK_OPT* check_opt) + { return HA_ADMIN_NOT_IMPLEMENTED; } + /** + Restore assumes .frm file must exist, and that generate_table() has been + called; It will just copy the data file and run repair. + */ + virtual int restore(THD* thd, HA_CHECK_OPT* check_opt) + { return HA_ADMIN_NOT_IMPLEMENTED; } + virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt) + { return HA_ADMIN_NOT_IMPLEMENTED; } + virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt) + { return HA_ADMIN_NOT_IMPLEMENTED; } + virtual bool check_and_repair(THD *thd) { return HA_ERR_WRONG_COMMAND; } + virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; } + virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; } + virtual int discard_or_import_tablespace(my_bool discard) + { return (my_errno=HA_ERR_WRONG_COMMAND); } + virtual void prepare_for_alter() { return; } + virtual void drop_table(const char *name); + virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0; + + virtual int create_handler_files(const char *name, const char *old_name, + int action_flag, HA_CREATE_INFO *info) + { return FALSE; } + + virtual int change_partitions(HA_CREATE_INFO *create_info, + const char *path, + ulonglong *copied, + ulonglong *deleted, + const uchar *pack_frm_data, + size_t pack_frm_len) + { return HA_ERR_WRONG_COMMAND; } + virtual int drop_partitions(const char *path) + { return HA_ERR_WRONG_COMMAND; } + virtual int rename_partitions(const char *path) + { return HA_ERR_WRONG_COMMAND; } + virtual int optimize_partitions(THD *thd) + { return HA_ERR_WRONG_COMMAND; } + virtual int analyze_partitions(THD *thd) + { return HA_ERR_WRONG_COMMAND; } + virtual int check_partitions(THD *thd) + { return HA_ERR_WRONG_COMMAND; } + virtual int repair_partitions(THD *thd) + { return HA_ERR_WRONG_COMMAND; } }; diff --git a/sql/item.cc b/sql/item.cc index c33e5da0ca4..c546badd8e7 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3418,7 +3418,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) @param thd current thread @param ref column reference being resolved - @param select the sub-select that ref is resolved against + @param select the select that ref is resolved against @note The resolution procedure is: @@ -3478,6 +3478,7 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) } if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && + select->having_fix_field && select_ref != not_found_item && !group_by_ref) { /* @@ -4460,7 +4461,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length) break; case MYSQL_TYPE_NEWDATE: case MYSQL_TYPE_DATE: - field= new Field_date(maybe_null, name, &my_charset_bin); + field= new Field_newdate(maybe_null, name, &my_charset_bin); break; case MYSQL_TYPE_TIME: field= new Field_time(maybe_null, name, &my_charset_bin); @@ -6695,6 +6696,8 @@ enum_field_types Item_type_holder::get_real_type(Item *item) */ Field *field= ((Item_field *) item)->field; enum_field_types type= field->real_type(); + if (field->is_created_from_null_item) + return MYSQL_TYPE_NULL; /* work around about varchar type field detection */ if (type == MYSQL_TYPE_STRING && field->type() == MYSQL_TYPE_VAR_STRING) return MYSQL_TYPE_VAR_STRING; @@ -6948,6 +6951,8 @@ Field *Item_type_holder::make_field_by_type(TABLE *table) if (field) field->init(table); return field; + case MYSQL_TYPE_NULL: + return make_string_field(table); default: break; } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 62ac7bc4751..dc868376796 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -975,7 +975,7 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, *is_null= item->null_value; } if (*is_null) - return -1; + return ~(ulonglong) 0; /* Convert strings to the integer DATE/DATETIME representation. Even if both dates provided in strings we can't compare them directly as diff --git a/sql/item_func.cc b/sql/item_func.cc index aa7f5bbb0d5..748624c0357 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1995,7 +1995,7 @@ void Item_func_round::fix_length_and_dec() int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1; precision-= decimals_delta - length_increase; - decimals= decimals_to_set; + decimals= min(decimals_to_set, DECIMAL_MAX_SCALE); max_length= my_decimal_precision_to_length(precision, decimals, unsigned_flag); break; @@ -2094,18 +2094,18 @@ my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value) { my_decimal val, *value= args[0]->val_decimal(&val); longlong dec= args[1]->val_int(); - if (dec > 0 || (dec < 0 && args[1]->unsigned_flag)) - { + if (dec >= 0 || args[1]->unsigned_flag) dec= min((ulonglong) dec, decimals); - decimals= (uint8) dec; // to get correct output - } else if (dec < INT_MIN) dec= INT_MIN; if (!(null_value= (args[0]->null_value || args[1]->null_value || my_decimal_round(E_DEC_FATAL_ERROR, value, (int) dec, - truncate, decimal_value) > 1))) + truncate, decimal_value) > 1))) + { + decimal_value->frac= decimals; return decimal_value; + } return 0; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 19c71cbc48d..27b964a9e15 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -632,7 +632,7 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table, */ switch (args[0]->field_type()) { case MYSQL_TYPE_DATE: - field= new Field_date(maybe_null, name, collation.collation); + field= new Field_newdate(maybe_null, name, collation.collation); break; case MYSQL_TYPE_TIME: field= new Field_time(maybe_null, name, collation.collation); @@ -2617,7 +2617,7 @@ void Item_sum_count_distinct::clear() else if (table) { table->file->extra(HA_EXTRA_NO_CACHE); - table->file->delete_all_rows(); + table->file->ha_delete_all_rows(); table->file->extra(HA_EXTRA_WRITE_CACHE); } } @@ -2863,44 +2863,51 @@ String *Item_sum_udf_str::val_str(String *str) concat of values from "group by" operation BUGS - DISTINCT and ORDER BY only works if ORDER BY uses all fields and only fields - in expression list Blobs doesn't work with DISTINCT or ORDER BY *****************************************************************************/ -/** - function of sort for syntax: GROUP_CONCAT(DISTINCT expr,...) + + +/** + Compares the values for fields in expr list of GROUP_CONCAT. + @note + + GROUP_CONCAT([DISTINCT] expr [,expr ...] + [ORDER BY {unsigned_integer | col_name | expr} + [ASC | DESC] [,col_name ...]] + [SEPARATOR str_val]) + + @return + @retval -1 : key1 < key2 + @retval 0 : key1 = key2 + @retval 1 : key1 > key2 */ -int group_concat_key_cmp_with_distinct(void* arg, uchar* key1, - uchar* key2) +int group_concat_key_cmp_with_distinct(void* arg, const void* key1, + const void* key2) { - Item_func_group_concat* grp_item= (Item_func_group_concat*)arg; - TABLE *table= grp_item->table; - Item **field_item, **end; + Item_func_group_concat *item_func= (Item_func_group_concat*)arg; + TABLE *table= item_func->table; - for (field_item= grp_item->args, end= field_item + grp_item->arg_count_field; - field_item < end; - field_item++) + for (uint i= 0; i < item_func->arg_count_field; i++) { + Item *item= item_func->args[i]; + /* + If field_item is a const item then either get_tp_table_field returns 0 + or it is an item over a const table. + */ + if (item->const_item()) + continue; /* We have to use get_tmp_table_field() instead of real_item()->get_tmp_table_field() because we want the field in the temporary table, not the original field */ - Field *field= (*field_item)->get_tmp_table_field(); - /* - If field_item is a const item then either get_tmp_table_field returns 0 - or it is an item over a const table. - */ - if (field && !(*field_item)->const_item()) - { - int res; - uint offset= (field->offset(field->table->record[0]) - - table->s->null_bytes); - if ((res= field->cmp(key1 + offset, key2 + offset))) - return res; - } + Field *field= item->get_tmp_table_field(); + int res; + uint offset= field->offset(field->table->record[0])-table->s->null_bytes; + if((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset))) + return res; } return 0; } @@ -2910,7 +2917,8 @@ int group_concat_key_cmp_with_distinct(void* arg, uchar* key1, function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... ) */ -int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2) +int group_concat_key_cmp_with_order(void* arg, const void* key1, + const void* key2) { Item_func_group_concat* grp_item= (Item_func_group_concat*) arg; ORDER **order_item, **end; @@ -2936,7 +2944,7 @@ int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2) int res; uint offset= (field->offset(field->table->record[0]) - table->s->null_bytes); - if ((res= field->cmp(key1 + offset, key2 + offset))) + if ((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset))) return (*order_item)->asc ? res : -res; } } @@ -2950,25 +2958,6 @@ int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2) /** - function of sort for syntax: - GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... ). - - @bug - This doesn't work in the case when the order by contains data that - is not part of the field list because tree-insert will not notice - the duplicated values when inserting things sorted by ORDER BY -*/ - -int group_concat_key_cmp_with_distinct_and_order(void* arg,uchar* key1, - uchar* key2) -{ - if (!group_concat_key_cmp_with_distinct(arg,key1,key2)) - return 0; - return(group_concat_key_cmp_with_order(arg,key1,key2)); -} - - -/** Append data from current leaf to item->result. */ @@ -3054,7 +3043,7 @@ Item_func_group_concat(Name_resolution_context *context_arg, bool distinct_arg, List<Item> *select_list, SQL_LIST *order_list, String *separator_arg) :tmp_table_param(0), warning(0), - separator(separator_arg), tree(0), table(0), + separator(separator_arg), tree(0), unique_filter(NULL), table(0), order(0), context(context_arg), arg_count_order(order_list ? order_list->elements : 0), arg_count_field(select_list->elements), @@ -3109,6 +3098,7 @@ Item_func_group_concat::Item_func_group_concat(THD *thd, warning(item->warning), separator(item->separator), tree(item->tree), + unique_filter(item->unique_filter), table(item->table), order(item->order), context(item->context), @@ -3159,6 +3149,11 @@ void Item_func_group_concat::cleanup() delete_tree(tree); tree= 0; } + if (unique_filter) + { + delete unique_filter; + unique_filter= NULL; + } if (warning) { char warn_buff[MYSQL_ERRMSG_SIZE]; @@ -3188,6 +3183,8 @@ void Item_func_group_concat::clear() no_appended= TRUE; if (tree) reset_tree(tree); + if (distinct) + unique_filter->reset(); /* No need to reset the table as we never call write_row */ } @@ -3211,9 +3208,19 @@ bool Item_func_group_concat::add() } null_value= FALSE; + bool row_eligible= TRUE; + + if (distinct) + { + /* Filter out duplicate rows. */ + uint count= unique_filter->elements_in_tree(); + unique_filter->unique_add(table->record[0] + table->s->null_bytes); + if (count == unique_filter->elements_in_tree()) + row_eligible= FALSE; + } TREE_ELEMENT *el= 0; // Only for safety - if (tree) + if (row_eligible && tree) el= tree_insert(tree, table->record[0] + table->s->null_bytes, 0, tree->custom_arg); /* @@ -3221,7 +3228,7 @@ bool Item_func_group_concat::add() we can dump the row here in case of GROUP_CONCAT(DISTINCT...) instead of doing tree traverse later. */ - if (!warning_for_row && + if (row_eligible && !warning_for_row && (!tree || (el->count == 1 && distinct && !arg_count_order))) dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this); @@ -3297,7 +3304,6 @@ bool Item_func_group_concat::setup(THD *thd) { List<Item> list; SELECT_LEX *select_lex= thd->lex->current_select; - qsort_cmp2 compare_key; DBUG_ENTER("Item_func_group_concat::setup"); /* @@ -3387,38 +3393,33 @@ bool Item_func_group_concat::setup(THD *thd) table->file->extra(HA_EXTRA_NO_ROWS); table->no_rows= 1; + /* + Need sorting or uniqueness: init tree and choose a function to sort. + Don't reserve space for NULLs: if any of gconcat arguments is NULL, + the row is not added to the result. + */ + uint tree_key_length= table->s->reclength - table->s->null_bytes; - if (distinct || arg_count_order) + if (arg_count_order) { - /* - Need sorting: init tree and choose a function to sort. - Don't reserve space for NULLs: if any of gconcat arguments is NULL, - the row is not added to the result. - */ - uint tree_key_length= table->s->reclength - table->s->null_bytes; - tree= &tree_base; - if (arg_count_order) - { - if (distinct) - compare_key= (qsort_cmp2) group_concat_key_cmp_with_distinct_and_order; - else - compare_key= (qsort_cmp2) group_concat_key_cmp_with_order; - } - else - { - compare_key= (qsort_cmp2) group_concat_key_cmp_with_distinct; - } /* - Create a tree for sorting. The tree is used to sort and to remove - duplicate values (according to the syntax of this function). If there - is no DISTINCT or ORDER BY clauses, we don't create this tree. + Create a tree for sorting. The tree is used to sort (according to the + syntax of this function). If there is no ORDER BY clause, we don't + create this tree. */ init_tree(tree, (uint) min(thd->variables.max_heap_table_size, thd->variables.sortbuff_size/16), 0, - tree_key_length, compare_key, 0, NULL, (void*) this); + tree_key_length, + group_concat_key_cmp_with_order , 0, NULL, (void*) this); } + if (distinct) + unique_filter= new Unique(group_concat_key_cmp_with_distinct, + (void*)this, + tree_key_length, + thd->variables.max_heap_table_size); + DBUG_RETURN(FALSE); } @@ -3488,3 +3489,10 @@ void Item_func_group_concat::print(String *str) str->append(*separator); str->append(STRING_WITH_LEN("\')")); } + + +Item_func_group_concat::~Item_func_group_concat() +{ + if (unique_filter) + delete unique_filter; +} diff --git a/sql/item_sum.h b/sql/item_sum.h index b3a382012f1..a3582967736 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1173,11 +1173,22 @@ class Item_func_group_concat : public Item_sum String *separator; TREE tree_base; TREE *tree; + + /** + If DISTINCT is used with this GROUP_CONCAT, this member is used to filter + out duplicates. + @see Item_func_group_concat::setup + @see Item_func_group_concat::add + @see Item_func_group_concat::clear + */ + Unique *unique_filter; TABLE *table; ORDER **order; Name_resolution_context *context; - uint arg_count_order; // total count of ORDER BY items - uint arg_count_field; // count of arguments + /** The number of ORDER BY items. */ + uint arg_count_order; + /** The number of selected items, aka the expr list. */ + uint arg_count_field; uint count_cut_values; bool distinct; bool warning_for_row; @@ -1190,13 +1201,10 @@ class Item_func_group_concat : public Item_sum */ Item_func_group_concat *original; - friend int group_concat_key_cmp_with_distinct(void* arg, uchar* key1, - uchar* key2); - friend int group_concat_key_cmp_with_order(void* arg, uchar* key1, - uchar* key2); - friend int group_concat_key_cmp_with_distinct_and_order(void* arg, - uchar* key1, - uchar* key2); + friend int group_concat_key_cmp_with_distinct(void* arg, const void* key1, + const void* key2); + friend int group_concat_key_cmp_with_order(void* arg, const void* key1, + const void* key2); friend int dump_leaf_key(uchar* key, element_count count __attribute__((unused)), Item_func_group_concat *group_concat_item); @@ -1207,7 +1215,7 @@ public: SQL_LIST *is_order, String *is_separator); Item_func_group_concat(THD *thd, Item_func_group_concat *item); - ~Item_func_group_concat() {} + ~Item_func_group_concat(); void cleanup(); enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;} diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index ce760b8fd2a..a0beadcd481 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -3360,6 +3360,8 @@ bool Item_func_last_day::get_date(MYSQL_TIME *ltime, uint fuzzy_date) ltime->day= days_in_month[month_idx]; if ( month_idx == 1 && calc_days_in_year(ltime->year) == 366) ltime->day= 29; + ltime->hour= ltime->minute= ltime->second= 0; + ltime->second_part= 0; ltime->time_type= MYSQL_TIMESTAMP_DATE; return 0; } diff --git a/sql/log.cc b/sql/log.cc index a0c35059902..ac8831495f5 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1420,6 +1420,21 @@ static int binlog_prepare(handlerton *hton, THD *thd, bool all) return 0; } +/** + This function is called once after each statement. + + It has the responsibility to flush the transaction cache to the + binlog file on commits. + + @param hton The binlog handlerton. + @param thd The client thread that executes the transaction. + @param all true if this is the last statement before a COMMIT + statement; false if either this is a statement in a + transaction but not the last, or if this is a statement + not inside a BEGIN block and autocommit is on. + + @see handlerton::commit +*/ static int binlog_commit(handlerton *hton, THD *thd, bool all) { DBUG_ENTER("binlog_commit"); @@ -1432,7 +1447,15 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all) trx_data->reset(); DBUG_RETURN(0); } - if (all) + /* + Write commit event if at least one of the following holds: + - the user sends an explicit COMMIT; or + - the autocommit flag is on, and we are not inside a BEGIN. + However, if the user has not sent an explicit COMMIT, and we are + either inside a BEGIN or run with autocommit off, then this is not + the end of a transaction and we should not write a commit event. + */ + if (all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE); qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE) @@ -1446,6 +1469,23 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all) } } +/** + This function is called when a transaction involving a transactional + table is rolled back. + + It has the responsibility to flush the transaction cache to the + binlog file. However, if the transaction does not involve + non-transactional tables, nothing needs to be logged. + + @param hton The binlog handlerton. + @param thd The client thread that executes the transaction. + @param all true if this is the last statement before a COMMIT + statement; false if either this is a statement in a + transaction but not the last, or if this is a statement + not inside a BEGIN block and autocommit is on. + + @see handlerton::rollback +*/ static int binlog_rollback(handlerton *hton, THD *thd, bool all) { DBUG_ENTER("binlog_rollback"); @@ -3023,10 +3063,10 @@ err: void MYSQL_BIN_LOG::make_log_name(char* buf, const char* log_ident) { uint dir_len = dirname_length(log_file_name); - if (dir_len > FN_REFLEN) + if (dir_len >= FN_REFLEN) dir_len=FN_REFLEN-1; strnmov(buf, log_file_name, dir_len); - strmake(buf+dir_len, log_ident, FN_REFLEN - dir_len); + strmake(buf+dir_len, log_ident, FN_REFLEN - dir_len -1); } @@ -4015,32 +4055,42 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) if (my_b_tell(cache) > 0) { /* - Log "BEGIN" at the beginning of the transaction. - which may contain more than 1 SQL statement. + Log "BEGIN" at the beginning of every transaction. Here, a + transaction is either a BEGIN..COMMIT block or a single + statement in autocommit mode. */ - if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) - { - Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE); - /* - Imagine this is rollback due to net timeout, after all statements of - the transaction succeeded. Then we want a zero-error code in BEGIN. - In other words, if there was a really serious error code it's already - in the statement's events, there is no need to put it also in this - internally generated event, and as this event is generated late it - would lead to false alarms. - This is safer than thd->clear_error() against kills at shutdown. - */ - qinfo.error_code= 0; - /* - Now this Query_log_event has artificial log_pos 0. It must be adjusted - to reflect the real position in the log. Not doing it would confuse the - slave: it would prevent this one from knowing where he is in the - master's binlog, which would result in wrong positions being shown to - the user, MASTER_POS_WAIT undue waiting etc. - */ - if (qinfo.write(&log_file)) - goto err; - } + Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE); + /* + Imagine this is rollback due to net timeout, after all + statements of the transaction succeeded. Then we want a + zero-error code in BEGIN. In other words, if there was a + really serious error code it's already in the statement's + events, there is no need to put it also in this internally + generated event, and as this event is generated late it would + lead to false alarms. + + This is safer than thd->clear_error() against kills at shutdown. + */ + qinfo.error_code= 0; + /* + Now this Query_log_event has artificial log_pos 0. It must be + adjusted to reflect the real position in the log. Not doing it + would confuse the slave: it would prevent this one from + knowing where he is in the master's binlog, which would result + in wrong positions being shown to the user, MASTER_POS_WAIT + undue waiting etc. + */ + if (qinfo.write(&log_file)) + goto err; + + DBUG_EXECUTE_IF("crash_before_writing_xid", + { + if ((write_error= write_cache(cache, false, true))) + DBUG_PRINT("info", ("error writing binlog cache: %d", + write_error)); + DBUG_PRINT("info", ("crashing before writing xid")); + abort(); + }); if ((write_error= write_cache(cache, false, false))) goto err; diff --git a/sql/log_event.cc b/sql/log_event.cc index cf03dd5bf44..df0d1e8a020 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -36,7 +36,17 @@ #define FLAGSTR(V,F) ((V)&(F)?#F" ":"") -#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) && !defined(DBUG_OFF) && !defined(_lint) + +/* + Size of buffer for printing a double in format %.<PREC>g + + optional '-' + optional zero + '.' + PREC digits + 'e' + sign + + exponent digits + '\0' +*/ +#define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1) + + +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) static const char *HA_ERR(int i) { switch (i) { @@ -90,7 +100,28 @@ static const char *HA_ERR(int i) case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE"; case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT"; } - return "<unknown error>"; + return 0; +} + +/** + macro to call from different branches of Rows_log_event::do_apply_event +*/ +static void inline slave_rows_error_report(enum loglevel level, int ha_error, + Relay_log_info const *rli, THD *thd, + TABLE *table, const char * type, + const char *log_name, ulong pos) +{ + const char *handler_error= HA_ERR(ha_error); + rli->report(level, thd->net.client_last_errno, + "Could not execute %s event on table %s.%s;" + "%s%s handler error %s; " + "the event's master log %s, end_log_pos %lu", + type, table->s->db.str, + table->s->table_name.str, + thd->net.client_last_error[0] != 0 ? thd->net.client_last_error : "", + thd->net.client_last_error[0] != 0 ? ";" : "", + handler_error == NULL? "<unknown>" : handler_error, + log_name, pos); } #endif @@ -460,9 +491,9 @@ static void print_set_option(IO_CACHE* file, uint32 bits_changed, returns the human readable name of the event's type */ -const char* Log_event::get_type_str() +const char* Log_event::get_type_str(Log_event_type type) { - switch(get_type_code()) { + switch(type) { case START_EVENT_V3: return "Start_v3"; case STOP_EVENT: return "Stop"; case QUERY_EVENT: return "Query"; @@ -480,6 +511,9 @@ const char* Log_event::get_type_str() case USER_VAR_EVENT: return "User var"; case FORMAT_DESCRIPTION_EVENT: return "Format_desc"; case TABLE_MAP_EVENT: return "Table_map"; + case PRE_GA_WRITE_ROWS_EVENT: return "Write_rows_event_old"; + case PRE_GA_UPDATE_ROWS_EVENT: return "Update_rows_event_old"; + case PRE_GA_DELETE_ROWS_EVENT: return "Delete_rows_event_old"; case WRITE_ROWS_EVENT: return "Write_rows"; case UPDATE_ROWS_EVENT: return "Update_rows"; case DELETE_ROWS_EVENT: return "Delete_rows"; @@ -490,6 +524,11 @@ const char* Log_event::get_type_str() } } +const char* Log_event::get_type_str() +{ + return get_type_str(get_type_code()); +} + /* Log_event::Log_event() @@ -997,6 +1036,8 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len, DBUG_ENTER("Log_event::read_log_event(char*,...)"); DBUG_ASSERT(description_event != 0); DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version)); + DBUG_DUMP("data", (unsigned char*) buf, event_len); + /* Check the integrity */ if (event_len < EVENT_LEN_OFFSET || buf[EVENT_TYPE_OFFSET] >= ENUM_END_EVENT || @@ -1006,94 +1047,134 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len, DBUG_RETURN(NULL); // general sanity check - will fail on a partial read } - switch(buf[EVENT_TYPE_OFFSET]) { - case QUERY_EVENT: - ev = new Query_log_event(buf, event_len, description_event, QUERY_EVENT); - break; - case LOAD_EVENT: - ev = new Load_log_event(buf, event_len, description_event); - break; - case NEW_LOAD_EVENT: - ev = new Load_log_event(buf, event_len, description_event); - break; - case ROTATE_EVENT: - ev = new Rotate_log_event(buf, event_len, description_event); - break; + uint event_type= buf[EVENT_TYPE_OFFSET]; + if (event_type > description_event->number_of_event_types && + event_type != FORMAT_DESCRIPTION_EVENT) + { + /* + It is unsafe to use the description_event if its post_header_len + array does not include the event type. + */ + DBUG_PRINT("error", ("event type %d found, but the current " + "Format_description_log_event supports only %d event " + "types", event_type, + description_event->number_of_event_types)); + ev= NULL; + } + else + { + /* + In some previuos versions (see comment in + Format_description_log_event::Format_description_log_event(char*,...)), + event types were assigned different id numbers than in the + present version. In order to replicate from such versions to the + present version, we must map those event type id's to our event + type id's. The mapping is done with the event_type_permutation + array, which was set up when the Format_description_log_event + was read. + */ + if (description_event->event_type_permutation) + { + IF_DBUG({ + int new_event_type= + description_event->event_type_permutation[event_type]; + DBUG_PRINT("info", + ("converting event type %d to %d (%s)", + event_type, new_event_type, + get_type_str((Log_event_type)new_event_type))); + }); + event_type= description_event->event_type_permutation[event_type]; + } + + switch(event_type) { + case QUERY_EVENT: + ev = new Query_log_event(buf, event_len, description_event, QUERY_EVENT); + break; + case LOAD_EVENT: + ev = new Load_log_event(buf, event_len, description_event); + break; + case NEW_LOAD_EVENT: + ev = new Load_log_event(buf, event_len, description_event); + break; + case ROTATE_EVENT: + ev = new Rotate_log_event(buf, event_len, description_event); + break; #ifdef HAVE_REPLICATION - case SLAVE_EVENT: /* can never happen (unused event) */ - ev = new Slave_log_event(buf, event_len); - break; + case SLAVE_EVENT: /* can never happen (unused event) */ + ev = new Slave_log_event(buf, event_len); + break; #endif /* HAVE_REPLICATION */ - case CREATE_FILE_EVENT: - ev = new Create_file_log_event(buf, event_len, description_event); - break; - case APPEND_BLOCK_EVENT: - ev = new Append_block_log_event(buf, event_len, description_event); - break; - case DELETE_FILE_EVENT: - ev = new Delete_file_log_event(buf, event_len, description_event); - break; - case EXEC_LOAD_EVENT: - ev = new Execute_load_log_event(buf, event_len, description_event); - break; - case START_EVENT_V3: /* this is sent only by MySQL <=4.x */ - ev = new Start_log_event_v3(buf, description_event); - break; - case STOP_EVENT: - ev = new Stop_log_event(buf, description_event); - break; - case INTVAR_EVENT: - ev = new Intvar_log_event(buf, description_event); - break; - case XID_EVENT: - ev = new Xid_log_event(buf, description_event); - break; - case RAND_EVENT: - ev = new Rand_log_event(buf, description_event); - break; - case USER_VAR_EVENT: - ev = new User_var_log_event(buf, description_event); - break; - case FORMAT_DESCRIPTION_EVENT: - ev = new Format_description_log_event(buf, event_len, description_event); - break; + case CREATE_FILE_EVENT: + ev = new Create_file_log_event(buf, event_len, description_event); + break; + case APPEND_BLOCK_EVENT: + ev = new Append_block_log_event(buf, event_len, description_event); + break; + case DELETE_FILE_EVENT: + ev = new Delete_file_log_event(buf, event_len, description_event); + break; + case EXEC_LOAD_EVENT: + ev = new Execute_load_log_event(buf, event_len, description_event); + break; + case START_EVENT_V3: /* this is sent only by MySQL <=4.x */ + ev = new Start_log_event_v3(buf, description_event); + break; + case STOP_EVENT: + ev = new Stop_log_event(buf, description_event); + break; + case INTVAR_EVENT: + ev = new Intvar_log_event(buf, description_event); + break; + case XID_EVENT: + ev = new Xid_log_event(buf, description_event); + break; + case RAND_EVENT: + ev = new Rand_log_event(buf, description_event); + break; + case USER_VAR_EVENT: + ev = new User_var_log_event(buf, description_event); + break; + case FORMAT_DESCRIPTION_EVENT: + ev = new Format_description_log_event(buf, event_len, description_event); + break; #if defined(HAVE_REPLICATION) - case PRE_GA_WRITE_ROWS_EVENT: - ev = new Write_rows_log_event_old(buf, event_len, description_event); - break; - case PRE_GA_UPDATE_ROWS_EVENT: - ev = new Update_rows_log_event_old(buf, event_len, description_event); - break; - case PRE_GA_DELETE_ROWS_EVENT: - ev = new Delete_rows_log_event_old(buf, event_len, description_event); - break; - case WRITE_ROWS_EVENT: - ev = new Write_rows_log_event(buf, event_len, description_event); - break; - case UPDATE_ROWS_EVENT: - ev = new Update_rows_log_event(buf, event_len, description_event); - break; - case DELETE_ROWS_EVENT: - ev = new Delete_rows_log_event(buf, event_len, description_event); - break; - case TABLE_MAP_EVENT: - ev = new Table_map_log_event(buf, event_len, description_event); - break; + case PRE_GA_WRITE_ROWS_EVENT: + ev = new Write_rows_log_event_old(buf, event_len, description_event); + break; + case PRE_GA_UPDATE_ROWS_EVENT: + ev = new Update_rows_log_event_old(buf, event_len, description_event); + break; + case PRE_GA_DELETE_ROWS_EVENT: + ev = new Delete_rows_log_event_old(buf, event_len, description_event); + break; + case WRITE_ROWS_EVENT: + ev = new Write_rows_log_event(buf, event_len, description_event); + break; + case UPDATE_ROWS_EVENT: + ev = new Update_rows_log_event(buf, event_len, description_event); + break; + case DELETE_ROWS_EVENT: + ev = new Delete_rows_log_event(buf, event_len, description_event); + break; + case TABLE_MAP_EVENT: + ev = new Table_map_log_event(buf, event_len, description_event); + break; #endif - case BEGIN_LOAD_QUERY_EVENT: - ev = new Begin_load_query_log_event(buf, event_len, description_event); - break; - case EXECUTE_LOAD_QUERY_EVENT: - ev= new Execute_load_query_log_event(buf, event_len, description_event); - break; - case INCIDENT_EVENT: - ev = new Incident_log_event(buf, event_len, description_event); - break; - default: - DBUG_PRINT("error",("Unknown event code: %d", - (int) buf[EVENT_TYPE_OFFSET])); - ev= NULL; - break; + case BEGIN_LOAD_QUERY_EVENT: + ev = new Begin_load_query_log_event(buf, event_len, description_event); + break; + case EXECUTE_LOAD_QUERY_EVENT: + ev= new Execute_load_query_log_event(buf, event_len, description_event); + break; + case INCIDENT_EVENT: + ev = new Incident_log_event(buf, event_len, description_event); + break; + default: + DBUG_PRINT("error",("Unknown event code: %d", + (int) buf[EVENT_TYPE_OFFSET])); + ev= NULL; + break; + } } DBUG_PRINT("read_event", ("%s(type_code: %d; event_len: %d)", @@ -1632,6 +1713,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, DBUG_ASSERT(thd_arg->variables.character_set_client->number < 256*256); DBUG_ASSERT(thd_arg->variables.collation_connection->number < 256*256); DBUG_ASSERT(thd_arg->variables.collation_server->number < 256*256); + DBUG_ASSERT(thd_arg->variables.character_set_client->mbminlen == 1); int2store(charset, thd_arg->variables.character_set_client->number); int2store(charset+2, thd_arg->variables.collation_connection->number); int2store(charset+4, thd_arg->variables.collation_server->number); @@ -2135,7 +2217,7 @@ void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info) print_query_header(&cache, print_event_info); my_b_write(&cache, (uchar*) query, q_len); - my_b_printf(&cache, "%s\n", print_event_info->delimiter); + my_b_printf(&cache, "\n%s\n", print_event_info->delimiter); } #endif /* MYSQL_CLIENT */ @@ -2580,6 +2662,14 @@ void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info) my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter); #endif } + if (temp_buf && + print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER && + !print_event_info->short_form) + { + my_b_printf(&cache, "BINLOG '\n"); + print_base64(&cache, print_event_info, FALSE); + print_event_info->printed_fd_event= TRUE; + } DBUG_VOID_RETURN; } #endif /* MYSQL_CLIENT */ @@ -2715,7 +2805,7 @@ int Start_log_event_v3::do_apply_event(Relay_log_info const *rli) Format_description_log_event:: Format_description_log_event(uint8 binlog_ver, const char* server_ver) - :Start_log_event_v3() + :Start_log_event_v3(), event_type_permutation(0) { binlog_version= binlog_ver; switch (binlog_ver) { @@ -2842,7 +2932,7 @@ Format_description_log_event(const char* buf, const Format_description_log_event* description_event) - :Start_log_event_v3(buf, description_event) + :Start_log_event_v3(buf, description_event), event_type_permutation(0) { DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)"); buf+= LOG_EVENT_MINIMAL_HEADER_LEN; @@ -2857,6 +2947,65 @@ Format_description_log_event(const char* buf, number_of_event_types* sizeof(*post_header_len), MYF(0)); calc_server_version_split(); + + /* + In some previous versions, the events were given other event type + id numbers than in the present version. When replicating from such + a version, we therefore set up an array that maps those id numbers + to the id numbers of the present server. + + If post_header_len is null, it means malloc failed, and is_valid + will fail, so there is no need to do anything. + + The trees which have wrong event id's are: + mysql-5.1-wl2325-5.0-drop6p13-alpha, mysql-5.1-wl2325-5.0-drop6, + mysql-5.1-wl2325-5.0, mysql-5.1-wl2325-no-dd (`grep -C2 + BEGIN_LOAD_QUERY_EVENT /home/bk/ * /sql/log_event.h`). The + corresponding version (`grep mysql, configure.in` in those trees) + strings are 5.2.2-a_drop6p13-alpha, 5.2.2-a_drop6p13c, + 5.1.5-a_drop5p20, 5.1.2-a_drop5p5. + */ + if (post_header_len && + (strncmp(server_version, "5.1.2-a_drop5", 13) == 0 || + strncmp(server_version, "5.1.5-a_drop5", 13) == 0 || + strncmp(server_version, "5.2.2-a_drop6", 13) == 0)) + { + if (number_of_event_types != 22) + { + DBUG_PRINT("info", (" number_of_event_types=%d", + number_of_event_types)); + /* this makes is_valid() return false. */ + my_free(post_header_len, MYF(MY_ALLOW_ZERO_PTR)); + post_header_len= NULL; + DBUG_VOID_RETURN; + } + static const uint8 perm[23]= + { + UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT, + INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT, + APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT, + NEW_LOAD_EVENT, + RAND_EVENT, USER_VAR_EVENT, + FORMAT_DESCRIPTION_EVENT, + TABLE_MAP_EVENT, + PRE_GA_WRITE_ROWS_EVENT, + PRE_GA_UPDATE_ROWS_EVENT, + PRE_GA_DELETE_ROWS_EVENT, + XID_EVENT, + BEGIN_LOAD_QUERY_EVENT, + EXECUTE_LOAD_QUERY_EVENT, + }; + event_type_permutation= perm; + /* + Since we use (permuted) event id's to index the post_header_len + array, we need to permute the post_header_len array too. + */ + uint8 post_header_len_temp[23]; + for (int i= 1; i < 23; i++) + post_header_len_temp[perm[i] - 1]= post_header_len[i - 1]; + for (int i= 0; i < 22; i++) + post_header_len[i] = post_header_len_temp[i]; + } DBUG_VOID_RETURN; } @@ -4267,6 +4416,7 @@ Xid_log_event(const char* buf, #ifndef MYSQL_CLIENT bool Xid_log_event::write(IO_CACHE* file) { + DBUG_EXECUTE_IF("do_not_write_xid", return 0;); return write_header(file, sizeof(xid)) || my_b_safe_write(file, (uchar*) &xid, sizeof(xid)); } @@ -4520,8 +4670,10 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info) switch (type) { case REAL_RESULT: double real_val; + char real_buf[FMT_G_BUFSIZE(14)]; float8get(real_val, val); - my_b_printf(&cache, ":=%.14g%s\n", real_val, print_event_info->delimiter); + my_sprintf(real_buf, (real_buf, "%.14g", real_val)); + my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter); break; case INT_RESULT: char int_buf[22]; @@ -4925,7 +5077,7 @@ Create_file_log_event(THD* thd_arg, sql_exchange* ex, const char* db_arg, const char* table_name_arg, List<Item>& fields_arg, enum enum_duplicates handle_dup, bool ignore, - char* block_arg, uint block_len_arg, bool using_trans) + uchar* block_arg, uint block_len_arg, bool using_trans) :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore, using_trans), fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg), @@ -5023,8 +5175,8 @@ Create_file_log_event::Create_file_log_event(const char* buf, uint len, Load_log_event::get_data_size() + create_file_header_len + 1); if (len < block_offset) - return; - block = (char*)buf + block_offset; + DBUG_VOID_RETURN; + block = (uchar*)buf + block_offset; block_len = len - block_offset; } else @@ -5182,7 +5334,7 @@ err: #ifndef MYSQL_CLIENT Append_block_log_event::Append_block_log_event(THD *thd_arg, const char *db_arg, - char *block_arg, + uchar *block_arg, uint block_len_arg, bool using_trans) :Log_event(thd_arg,0, using_trans), block(block_arg), @@ -5208,7 +5360,7 @@ Append_block_log_event::Append_block_log_event(const char* buf, uint len, if (len < total_header_len) DBUG_VOID_RETURN; file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET); - block= (char*)buf + total_header_len; + block= (uchar*)buf + total_header_len; block_len= len - total_header_len; DBUG_VOID_RETURN; } @@ -5600,7 +5752,7 @@ err: #ifndef MYSQL_CLIENT Begin_load_query_log_event:: -Begin_load_query_log_event(THD* thd_arg, const char* db_arg, char* block_arg, +Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg, uint block_len_arg, bool using_trans) :Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg, using_trans) @@ -5732,12 +5884,12 @@ void Execute_load_query_log_event::print(FILE* file, my_b_printf(&cache, " REPLACE"); my_b_printf(&cache, " INTO"); my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end); - my_b_printf(&cache, "%s\n", print_event_info->delimiter); + my_b_printf(&cache, "\n%s\n", print_event_info->delimiter); } else { my_b_write(&cache, (uchar*) query, q_len); - my_b_printf(&cache, "%s\n", print_event_info->delimiter); + my_b_printf(&cache, "\n%s\n", print_event_info->delimiter); } if (!print_event_info->short_form) @@ -6180,7 +6332,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) { DBUG_ENTER("Rows_log_event::do_apply_event(Relay_log_info*)"); int error= 0; - /* If m_table_id == ~0UL, then we have a dummy event that does not contain any data. In that case, we just remove all tables in the @@ -6226,6 +6377,24 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) */ lex_start(thd); + /* + There are a few flags that are replicated with each row event. + Make sure to set/clear them before executing the main body of + the event. + */ + if (get_flags(NO_FOREIGN_KEY_CHECKS_F)) + thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS; + else + thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS; + + if (get_flags(RELAXED_UNIQUE_CHECKS_F)) + thd->options|= OPTION_RELAXED_UNIQUE_CHECKS; + else + thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS; + /* A small test to verify that objects have consistent types */ + DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS)); + + while ((error= lock_tables(thd, rli->tables_to_lock, rli->tables_to_lock_count, &need_reopen))) { @@ -6360,22 +6529,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) So we call set_time(), like in SBR. Presently it changes nothing. */ thd->set_time((time_t)when); - /* - There are a few flags that are replicated with each row event. - Make sure to set/clear them before executing the main body of - the event. - */ - if (get_flags(NO_FOREIGN_KEY_CHECKS_F)) - thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS; - else - thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS; - - if (get_flags(RELAXED_UNIQUE_CHECKS_F)) - thd->options|= OPTION_RELAXED_UNIQUE_CHECKS; - else - thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS; - /* A small test to verify that objects have consistent types */ - DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS)); /* Now we are in a statement and will stay in a statement until we @@ -6408,8 +6561,9 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) if (!get_flags(COMPLETE_ROWS_F)) bitmap_intersect(table->write_set,&m_cols); + this->slave_exec_mode= slave_exec_mode_options; // fix the mode + // Do event specific preparations - error= do_before_row_operations(rli); // row processing loop @@ -6428,23 +6582,41 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) { case 0: break; - - /* Some recoverable errors */ + /* + The following list of "idempotent" errors + means that an error from the list might happen + because of idempotent (more than once) + applying of a binlog file. + Notice, that binlog has a ddl operation its + second applying may cause + + case HA_ERR_TABLE_DEF_CHANGED: + case HA_ERR_CANNOT_ADD_FOREIGN: + + which are not included into to the list. + */ case HA_ERR_RECORD_CHANGED: case HA_ERR_RECORD_DELETED: case HA_ERR_KEY_NOT_FOUND: case HA_ERR_END_OF_FILE: - /* Idempotency support: OK if tuple does not exist */ + case HA_ERR_FOUND_DUPP_KEY: + case HA_ERR_FOUND_DUPP_UNIQUE: + case HA_ERR_FOREIGN_DUPLICATE_KEY: + case HA_ERR_NO_REFERENCED_ROW: + case HA_ERR_ROW_IS_REFERENCED: + DBUG_PRINT("info", ("error: %s", HA_ERR(error))); - error= 0; + if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1) + { + if (global_system_variables.log_warnings) + slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table, + get_type_str(), + RPL_LOG_NAME, (ulong) log_pos); + error= 0; + } break; - + default: - rli->report(ERROR_LEVEL, - thd->is_error() ? thd->main_da.sql_errno() : 0, - "Error in %s event: row application failed. %s", - get_type_str(), - thd->is_error() ? thd->main_da.message() : ""); thd->is_slave_error= 1; break; } @@ -6488,17 +6660,14 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) */ if (rli->tables_to_lock && get_flags(STMT_END_F)) const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); - + if (error) { /* error has occured during the transaction */ - rli->report(ERROR_LEVEL, - thd->is_error() ? thd->main_da.sql_errno() : 0, - "Error in %s event: error during transaction execution " - "on table %s.%s. %s", - get_type_str(), table->s->db.str, - table->s->table_name.str, - thd->is_error() ? thd->main_da.message() : ""); - + slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table, + get_type_str(), RPL_LOG_NAME, (ulong) log_pos); + } + if (error) + { /* If one day we honour --skip-slave-errors in row-based replication, and the error should be skipped, then we would clear mappings, rollback, @@ -6610,6 +6779,7 @@ Rows_log_event::do_update_pos(Relay_log_info *rli) */ thd->reset_current_stmt_binlog_row_based(); + rli->cleanup_context(thd, 0); if (error == 0) { @@ -7299,43 +7469,50 @@ Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability { int error= 0; - /* - We are using REPLACE semantics and not INSERT IGNORE semantics - when writing rows, that is: new rows replace old rows. We need to - inform the storage engine that it should use this behaviour. + /** + todo: to introduce a property for the event (handler?) which forces + applying the event in the replace (idempotent) fashion. */ + if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1 || + m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER) + { + /* + We are using REPLACE semantics and not INSERT IGNORE semantics + when writing rows, that is: new rows replace old rows. We need to + inform the storage engine that it should use this behaviour. + */ + + /* Tell the storage engine that we are using REPLACE semantics. */ + thd->lex->duplicates= DUP_REPLACE; + + /* + Pretend we're executing a REPLACE command: this is needed for + InnoDB and NDB Cluster since they are not (properly) checking the + lex->duplicates flag. + */ + thd->lex->sql_command= SQLCOM_REPLACE; + /* + Do not raise the error flag in case of hitting to an unique attribute + */ + m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); + /* + NDB specific: update from ndb master wrapped as Write_rows + so that the event should be applied to replace slave's row + */ + m_table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE); + /* + NDB specific: if update from ndb master wrapped as Write_rows + does not find the row it's assumed idempotent binlog applying + is taking place; don't raise the error. + */ + m_table->file->extra(HA_EXTRA_IGNORE_NO_KEY); + /* + TODO: the cluster team (Tomas?) says that it's better if the engine knows + how many rows are going to be inserted, then it can allocate needed memory + from the start. + */ + } - /* Tell the storage engine that we are using REPLACE semantics. */ - thd->lex->duplicates= DUP_REPLACE; - - /* - Pretend we're executing a REPLACE command: this is needed for - InnoDB and NDB Cluster since they are not (properly) checking the - lex->duplicates flag. - */ - thd->lex->sql_command= SQLCOM_REPLACE; - /* - Do not raise the error flag in case of hitting to an unique attribute - */ - m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); - /* - NDB specific: update from ndb master wrapped as Write_rows - */ - /* - so that the event should be applied to replace slave's row - */ - m_table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE); - /* - NDB specific: if update from ndb master wrapped as Write_rows - does not find the row it's assumed idempotent binlog applying - is taking place; don't raise the error. - */ - m_table->file->extra(HA_EXTRA_IGNORE_NO_KEY); - /* - TODO: the cluster team (Tomas?) says that it's better if the engine knows - how many rows are going to be inserted, then it can allocate needed memory - from the start. - */ m_table->file->ha_start_bulk_insert(0); /* We need TIMESTAMP_NO_AUTO_SET otherwise ha_write_row() will not use fill @@ -7357,18 +7534,23 @@ Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability } int -Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const, +Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const, int error) { int local_error= 0; - m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); - m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); - /* - reseting the extra with - table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY); - fires bug#27077 - todo: explain or fix - */ + if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1 || + m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER) + { + m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); + m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); + /* + resetting the extra with + table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY); + fires bug#27077 + explanation: file->reset() performs this duty + ultimately. Still todo: fix + */ + } if ((local_error= m_table->file->ha_end_bulk_insert())) { m_table->file->print_error(local_error, MYF(0)); @@ -7487,23 +7669,22 @@ Rows_log_event::write_row(const Relay_log_info *const rli, while ((error= table->file->ha_write_row(table->record[0]))) { - if (error == HA_ERR_LOCK_DEADLOCK || error == HA_ERR_LOCK_WAIT_TIMEOUT) - { - table->file->print_error(error, MYF(0)); /* to check at exec_relay_log_event */ - DBUG_RETURN(error); - } - if ((keynum= table->file->get_dup_key(error)) < 0) + if (error == HA_ERR_LOCK_DEADLOCK || + error == HA_ERR_LOCK_WAIT_TIMEOUT || + (keynum= table->file->get_dup_key(error)) < 0 || + !overwrite) { - DBUG_PRINT("info",("Can't locate duplicate key (get_dup_key returns %d)",keynum)); - table->file->print_error(error, MYF(0)); + DBUG_PRINT("info",("get_dup_key returns %d)", keynum)); /* - We failed to retrieve the duplicate key + Deadlock, waiting for lock or just an error from the handler + such as HA_ERR_FOUND_DUPP_KEY when overwrite is false. + Retrieval of the duplicate key number may fail - either because the error was not "duplicate key" error - or because the information which key is not available */ + table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } - /* We need to retrieve the old row into record[1] to be able to either update or delete the offending record. We either: @@ -7641,14 +7822,16 @@ int Write_rows_log_event::do_exec_row(const Relay_log_info *const rli) { DBUG_ASSERT(m_table != NULL); - int error= write_row(rli, TRUE /* overwrite */); - + int error= + write_row(rli, /* if 1 then overwrite */ + bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1); + if (error && !thd->is_error()) { DBUG_ASSERT(0); my_error(ER_UNKNOWN_ERROR, MYF(0)); } - + return error; } diff --git a/sql/log_event.h b/sql/log_event.h index 4bd496af2a4..efb8675780e 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -567,6 +567,15 @@ class Format_description_log_event; class Relay_log_info; #ifdef MYSQL_CLIENT +enum enum_base64_output_mode { + BASE64_OUTPUT_NEVER= 0, + BASE64_OUTPUT_AUTO= 1, + BASE64_OUTPUT_ALWAYS= 2, + BASE64_OUTPUT_UNSPEC= 3, + /* insert new output modes here */ + BASE64_OUTPUT_MODE_COUNT +}; + /* A structure for mysqlbinlog to know how to print events @@ -600,7 +609,8 @@ typedef struct st_print_event_info st_print_event_info() :flags2_inited(0), sql_mode_inited(0), auto_increment_increment(1),auto_increment_offset(1), charset_inited(0), - lc_time_names_number(0), charset_database_number(0) + lc_time_names_number(0), charset_database_number(0), + base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(FALSE) { /* Currently we only use static PRINT_EVENT_INFO objects, so zeroed at @@ -627,7 +637,14 @@ typedef struct st_print_event_info /* Settings on how to print the events */ bool short_form; - bool base64_output; + enum_base64_output_mode base64_output_mode; + /* + This is set whenever a Format_description_event is printed. + Later, when an event is printed in base64, this flag is tested: if + no Format_description_event has been seen, it is unsafe to print + the base64 event, so an error message is generated. + */ + bool printed_fd_event; my_off_t hexdump_from; uint8 common_header_len; char delimiter[16]; @@ -809,6 +826,12 @@ public: bool cache_stmt; + /** + A storage to cache the global system variable's value. + Handling of a separate event will be governed its member. + */ + ulong slave_exec_mode; + #ifndef MYSQL_CLIENT THD* thd; @@ -930,7 +953,13 @@ public: const char **error, const Format_description_log_event *description_event); - /* returns the human readable name of the event's type */ + /** + Returns the human readable name of the given event type. + */ + static const char* get_type_str(Log_event_type type); + /** + Returns the human readable name of this event's type. + */ const char* get_type_str(); /* Return start of query time or current time */ @@ -2077,12 +2106,16 @@ public: /* The list of post-headers' lengthes */ uint8 *post_header_len; uchar server_version_split[3]; + const uint8 *event_type_permutation; Format_description_log_event(uint8 binlog_ver, const char* server_ver=0); Format_description_log_event(const char* buf, uint event_len, const Format_description_log_event *description_event); - ~Format_description_log_event() { my_free((uchar*)post_header_len, MYF(0)); } + ~Format_description_log_event() + { + my_free((uchar*)post_header_len, MYF(MY_ALLOW_ZERO_PTR)); + } Log_event_type get_type_code() { return FORMAT_DESCRIPTION_EVENT;} #ifndef MYSQL_CLIENT bool write(IO_CACHE* file); @@ -2486,7 +2519,7 @@ protected: */ bool fake_base; public: - char* block; + uchar* block; const char *event_buf; uint block_len; uint file_id; @@ -2497,7 +2530,7 @@ public: const char* table_name_arg, List<Item>& fields_arg, enum enum_duplicates handle_dup, bool ignore, - char* block_arg, uint block_len_arg, + uchar* block_arg, uint block_len_arg, bool using_trans); #ifdef HAVE_REPLICATION void pack_info(Protocol* protocol); @@ -2552,7 +2585,7 @@ private: class Append_block_log_event: public Log_event { public: - char* block; + uchar* block; uint block_len; uint file_id; /* @@ -2569,7 +2602,7 @@ public: const char* db; #ifndef MYSQL_CLIENT - Append_block_log_event(THD* thd, const char* db_arg, char* block_arg, + Append_block_log_event(THD* thd, const char* db_arg, uchar* block_arg, uint block_len_arg, bool using_trans); #ifdef HAVE_REPLICATION void pack_info(Protocol* protocol); @@ -2693,7 +2726,7 @@ class Begin_load_query_log_event: public Append_block_log_event public: #ifndef MYSQL_CLIENT Begin_load_query_log_event(THD* thd_arg, const char *db_arg, - char* block_arg, uint block_len_arg, + uchar* block_arg, uint block_len_arg, bool using_trans); #ifdef HAVE_REPLICATION Begin_load_query_log_event(THD* thd); diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 6d5d86e42fe..7621bdc6291 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -11,9 +11,9 @@ // Old implementation of do_apply_event() int -Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli) +Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info *rli) { - DBUG_ENTER("Rows_log_event::do_apply_event(st_relay_log_info*)"); + DBUG_ENTER("Old_rows_log_event::do_apply_event(st_relay_log_info*)"); int error= 0; THD *thd= ev->thd; uchar const *row_start= ev->m_rows_buf; @@ -30,7 +30,7 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli This one is supposed to be set: just an extra check so that nothing strange has happened. */ - DBUG_ASSERT(ev->get_flags(Rows_log_event::STMT_END_F)); + DBUG_ASSERT(ev->get_flags(Old_rows_log_event::STMT_END_F)); const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); close_thread_tables(thd); @@ -148,7 +148,7 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli thd->lock= 0; thd->is_slave_error= 1; const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); - DBUG_RETURN(Rows_log_event::ERR_BAD_TABLE_DEF); + DBUG_RETURN(Old_rows_log_event::ERR_BAD_TABLE_DEF); } } } @@ -163,8 +163,8 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli TODO [/Matz]: Maybe the query cache should not be invalidated here? It might be that a table is not changed, even though it was locked for the statement. We do know that each - Rows_log_event contain at least one row, so after processing one - Rows_log_event, we can invalidate the query cache for the + Old_rows_log_event contain at least one row, so after processing one + Old_rows_log_event, we can invalidate the query cache for the associated table. */ for (TABLE_LIST *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global) @@ -200,12 +200,12 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli Make sure to set/clear them before executing the main body of the event. */ - if (ev->get_flags(Rows_log_event::NO_FOREIGN_KEY_CHECKS_F)) + if (ev->get_flags(Old_rows_log_event::NO_FOREIGN_KEY_CHECKS_F)) thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS; else thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS; - if (ev->get_flags(Rows_log_event::RELAXED_UNIQUE_CHECKS_F)) + if (ev->get_flags(Old_rows_log_event::RELAXED_UNIQUE_CHECKS_F)) thd->options|= OPTION_RELAXED_UNIQUE_CHECKS; else thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS; @@ -275,7 +275,7 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli We need to delay this clear until the table def is no longer needed. The table def is needed in unpack_row(). */ - if (rli->tables_to_lock && ev->get_flags(Rows_log_event::STMT_END_F)) + if (rli->tables_to_lock && ev->get_flags(Old_rows_log_event::STMT_END_F)) const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); if (error) @@ -311,7 +311,7 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli */ if (table && (table->s->primary_key == MAX_KEY) && !ev->cache_stmt && - ev->get_flags(Rows_log_event::STMT_END_F) == Rows_log_event::RLE_NO_FLAGS) + ev->get_flags(Old_rows_log_event::STMT_END_F) == Old_rows_log_event::RLE_NO_FLAGS) { /* ------------ Temporary fix until WL#2975 is implemented --------- @@ -323,7 +323,7 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli present, and idempotency is not guaranteed (no PK) so we risk that repeating leads to double insert. So we desperately try to continue, hope we'll eventually leave this buggy situation (by - executing the final Rows_log_event). If we are in a hopeless + executing the final Old_rows_log_event). If we are in a hopeless wait (reached end of last relay log and nothing gets appended there), we timeout after one minute, and notify DBA about the problem. When WL#2975 is implemented, just remove the member @@ -336,6 +336,7 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli } #endif + #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) /* @@ -350,6 +351,7 @@ last_uniq_key(TABLE *table, uint keyno) return 1; } + /* Compares table->record[0] and table->record[1] @@ -428,6 +430,7 @@ record_compare_exit: return result; } + /* Copy "extra" columns from record[1] to record[0]. @@ -516,6 +519,7 @@ copy_extra_record_fields(TABLE *table, DBUG_RETURN(0); // All OK } + /* Replace the provided record in the database. @@ -668,6 +672,7 @@ replace_record(THD *thd, TABLE *table, DBUG_RETURN(error); } + /** Find the row given by 'key', if the table has keys, or else use a table scan to find (and fetch) the row. @@ -879,6 +884,7 @@ static int find_and_fetch_row(TABLE *table, uchar *key) DBUG_RETURN(0); } + /********************************************************** Row handling primitives for Write_rows_log_event_old **********************************************************/ @@ -944,6 +950,7 @@ int Write_rows_log_event_old::do_before_row_operations(TABLE *table) return error; } + int Write_rows_log_event_old::do_after_row_operations(TABLE *table, int error) { int local_error= 0; @@ -962,6 +969,7 @@ int Write_rows_log_event_old::do_after_row_operations(TABLE *table, int error) return error? error : local_error; } + int Write_rows_log_event_old::do_prepare_row(THD *thd_arg, Relay_log_info const *rli, @@ -981,6 +989,7 @@ Write_rows_log_event_old::do_prepare_row(THD *thd_arg, return error; } + int Write_rows_log_event_old::do_exec_row(TABLE *table) { DBUG_ASSERT(table != NULL); @@ -988,6 +997,7 @@ int Write_rows_log_event_old::do_exec_row(TABLE *table) return error; } + /********************************************************** Row handling primitives for Delete_rows_log_event_old **********************************************************/ @@ -1029,6 +1039,7 @@ int Delete_rows_log_event_old::do_before_row_operations(TABLE *table) return error; } + int Delete_rows_log_event_old::do_after_row_operations(TABLE *table, int error) { /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/ @@ -1041,6 +1052,7 @@ int Delete_rows_log_event_old::do_after_row_operations(TABLE *table, int error) return error; } + int Delete_rows_log_event_old::do_prepare_row(THD *thd_arg, Relay_log_info const *rli, @@ -1074,6 +1086,7 @@ Delete_rows_log_event_old::do_prepare_row(THD *thd_arg, return error; } + int Delete_rows_log_event_old::do_exec_row(TABLE *table) { int error; @@ -1091,6 +1104,7 @@ int Delete_rows_log_event_old::do_exec_row(TABLE *table) return error; } + /********************************************************** Row handling primitives for Update_rows_log_event_old **********************************************************/ @@ -1124,6 +1138,7 @@ int Update_rows_log_event_old::do_before_row_operations(TABLE *table) return error; } + int Update_rows_log_event_old::do_after_row_operations(TABLE *table, int error) { /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/ @@ -1136,6 +1151,7 @@ int Update_rows_log_event_old::do_after_row_operations(TABLE *table, int error) return error; } + int Update_rows_log_event_old::do_prepare_row(THD *thd_arg, Relay_log_info const *rli, TABLE *table, @@ -1179,6 +1195,7 @@ int Update_rows_log_event_old::do_prepare_row(THD *thd_arg, return error; } + int Update_rows_log_event_old::do_exec_row(TABLE *table) { DBUG_ASSERT(table != NULL); @@ -1217,3 +1234,1676 @@ int Update_rows_log_event_old::do_exec_row(TABLE *table) } #endif + + +/************************************************************************** + Rows_log_event member functions +**************************************************************************/ + +#ifndef MYSQL_CLIENT +Old_rows_log_event::Old_rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid, + MY_BITMAP const *cols, + bool is_transactional) + : Log_event(thd_arg, 0, is_transactional), + m_row_count(0), + m_table(tbl_arg), + m_table_id(tid), + m_width(tbl_arg ? tbl_arg->s->fields : 1), + m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0) +#ifdef HAVE_REPLICATION + , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL) +#endif +{ + + // This constructor should not be reached. + assert(0); + + /* + We allow a special form of dummy event when the table, and cols + are null and the table id is ~0UL. This is a temporary + solution, to be able to terminate a started statement in the + binary log: the extraneous events will be removed in the future. + */ + DBUG_ASSERT(tbl_arg && tbl_arg->s && tid != ~0UL || + !tbl_arg && !cols && tid == ~0UL); + + if (thd_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS) + set_flags(NO_FOREIGN_KEY_CHECKS_F); + if (thd_arg->options & OPTION_RELAXED_UNIQUE_CHECKS) + set_flags(RELAXED_UNIQUE_CHECKS_F); + /* if bitmap_init fails, caught in is_valid() */ + if (likely(!bitmap_init(&m_cols, + m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, + m_width, + false))) + { + /* Cols can be zero if this is a dummy binrows event */ + if (likely(cols != NULL)) + { + memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols)); + create_last_word_mask(&m_cols); + } + } + else + { + // Needed because bitmap_init() does not set it to null on failure + m_cols.bitmap= 0; + } +} +#endif + + +Old_rows_log_event::Old_rows_log_event(const char *buf, uint event_len, + Log_event_type event_type, + const Format_description_log_event + *description_event) + : Log_event(buf, description_event), + m_row_count(0), +#ifndef MYSQL_CLIENT + m_table(NULL), +#endif + m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0) +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL) +#endif +{ + DBUG_ENTER("Old_rows_log_event::Old_Rows_log_event(const char*,...)"); + uint8 const common_header_len= description_event->common_header_len; + uint8 const post_header_len= description_event->post_header_len[event_type-1]; + + DBUG_PRINT("enter",("event_len: %u common_header_len: %d " + "post_header_len: %d", + event_len, common_header_len, + post_header_len)); + + const char *post_start= buf + common_header_len; + DBUG_DUMP("post_header", (uchar*) post_start, post_header_len); + post_start+= RW_MAPID_OFFSET; + if (post_header_len == 6) + { + /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */ + m_table_id= uint4korr(post_start); + post_start+= 4; + } + else + { + m_table_id= (ulong) uint6korr(post_start); + post_start+= RW_FLAGS_OFFSET; + } + + m_flags= uint2korr(post_start); + + uchar const *const var_start= + (const uchar *)buf + common_header_len + post_header_len; + uchar const *const ptr_width= var_start; + uchar *ptr_after_width= (uchar*) ptr_width; + DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); + m_width = net_field_length(&ptr_after_width); + DBUG_PRINT("debug", ("m_width=%lu", m_width)); + /* if bitmap_init fails, catched in is_valid() */ + if (likely(!bitmap_init(&m_cols, + m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, + m_width, + false))) + { + DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); + memcpy(m_cols.bitmap, ptr_after_width, (m_width + 7) / 8); + create_last_word_mask(&m_cols); + ptr_after_width+= (m_width + 7) / 8; + DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols)); + } + else + { + // Needed because bitmap_init() does not set it to null on failure + m_cols.bitmap= NULL; + DBUG_VOID_RETURN; + } + + const uchar* const ptr_rows_data= (const uchar*) ptr_after_width; + size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf); + DBUG_PRINT("info",("m_table_id: %lu m_flags: %d m_width: %lu data_size: %lu", + m_table_id, m_flags, m_width, (ulong) data_size)); + DBUG_DUMP("rows_data", (uchar*) ptr_rows_data, data_size); + + m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME)); + if (likely((bool)m_rows_buf)) + { +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + m_curr_row= m_rows_buf; +#endif + m_rows_end= m_rows_buf + data_size; + m_rows_cur= m_rows_end; + memcpy(m_rows_buf, ptr_rows_data, data_size); + } + else + m_cols.bitmap= 0; // to not free it + + DBUG_VOID_RETURN; +} + + +Old_rows_log_event::~Old_rows_log_event() +{ + if (m_cols.bitmap == m_bitbuf) // no my_malloc happened + m_cols.bitmap= 0; // so no my_free in bitmap_free + bitmap_free(&m_cols); // To pair with bitmap_init(). + my_free((uchar*)m_rows_buf, MYF(MY_ALLOW_ZERO_PTR)); +} + + +int Old_rows_log_event::get_data_size() +{ + uchar buf[sizeof(m_width)+1]; + uchar *end= net_store_length(buf, (m_width + 7) / 8); + + DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", + return 6 + no_bytes_in_map(&m_cols) + (end - buf) + + (m_rows_cur - m_rows_buf);); + int data_size= ROWS_HEADER_LEN; + data_size+= no_bytes_in_map(&m_cols); + data_size+= end - buf; + + data_size+= (m_rows_cur - m_rows_buf); + return data_size; +} + + +#ifndef MYSQL_CLIENT +int Old_rows_log_event::do_add_row_data(uchar *row_data, size_t length) +{ + /* + When the table has a primary key, we would probably want, by default, to + log only the primary key value instead of the entire "before image". This + would save binlog space. TODO + */ + DBUG_ENTER("Old_rows_log_event::do_add_row_data"); + DBUG_PRINT("enter", ("row_data: 0x%lx length: %lu", (ulong) row_data, + (ulong) length)); + /* + Don't print debug messages when running valgrind since they can + trigger false warnings. + */ +#ifndef HAVE_purify + DBUG_DUMP("row_data", row_data, min(length, 32)); +#endif + + DBUG_ASSERT(m_rows_buf <= m_rows_cur); + DBUG_ASSERT(!m_rows_buf || m_rows_end && m_rows_buf < m_rows_end); + DBUG_ASSERT(m_rows_cur <= m_rows_end); + + /* The cast will always work since m_rows_cur <= m_rows_end */ + if (static_cast<size_t>(m_rows_end - m_rows_cur) <= length) + { + size_t const block_size= 1024; + my_ptrdiff_t const cur_size= m_rows_cur - m_rows_buf; + my_ptrdiff_t const new_alloc= + block_size * ((cur_size + length + block_size - 1) / block_size); + + uchar* const new_buf= (uchar*)my_realloc((uchar*)m_rows_buf, (uint) new_alloc, + MYF(MY_ALLOW_ZERO_PTR|MY_WME)); + if (unlikely(!new_buf)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + + /* If the memory moved, we need to move the pointers */ + if (new_buf != m_rows_buf) + { + m_rows_buf= new_buf; + m_rows_cur= m_rows_buf + cur_size; + } + + /* + The end pointer should always be changed to point to the end of + the allocated memory. + */ + m_rows_end= m_rows_buf + new_alloc; + } + + DBUG_ASSERT(m_rows_cur + length <= m_rows_end); + memcpy(m_rows_cur, row_data, length); + m_rows_cur+= length; + m_row_count++; + DBUG_RETURN(0); +} +#endif + + +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) +int Old_rows_log_event::do_apply_event(Relay_log_info const *rli) +{ + DBUG_ENTER("Old_rows_log_event::do_apply_event(Relay_log_info*)"); + int error= 0; + + /* + If m_table_id == ~0UL, then we have a dummy event that does not + contain any data. In that case, we just remove all tables in the + tables_to_lock list, close the thread tables, and return with + success. + */ + if (m_table_id == ~0UL) + { + /* + This one is supposed to be set: just an extra check so that + nothing strange has happened. + */ + DBUG_ASSERT(get_flags(STMT_END_F)); + + const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); + close_thread_tables(thd); + thd->clear_error(); + DBUG_RETURN(0); + } + + /* + 'thd' has been set by exec_relay_log_event(), just before calling + do_apply_event(). We still check here to prevent future coding + errors. + */ + DBUG_ASSERT(rli->sql_thd == thd); + + /* + If there is no locks taken, this is the first binrow event seen + after the table map events. We should then lock all the tables + used in the transaction and proceed with execution of the actual + event. + */ + if (!thd->lock) + { + bool need_reopen= 1; /* To execute the first lap of the loop below */ + + /* + lock_tables() reads the contents of thd->lex, so they must be + initialized. Contrary to in + Table_map_log_event::do_apply_event() we don't call + mysql_init_query() as that may reset the binlog format. + */ + lex_start(thd); + + while ((error= lock_tables(thd, rli->tables_to_lock, + rli->tables_to_lock_count, &need_reopen))) + { + if (!need_reopen) + { + if (thd->is_slave_error || thd->is_fatal_error) + { + /* + Error reporting borrowed from Query_log_event with many excessive + simplifications (we don't honour --slave-skip-errors) + */ + uint actual_error= thd->net.client_last_errno; + rli->report(ERROR_LEVEL, actual_error, + "Error '%s' in %s event: when locking tables", + (actual_error ? thd->net.client_last_error : + "unexpected success or fatal error"), + get_type_str()); + thd->is_fatal_error= 1; + } + else + { + rli->report(ERROR_LEVEL, error, + "Error in %s event: when locking tables", + get_type_str()); + } + const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); + DBUG_RETURN(error); + } + + /* + So we need to reopen the tables. + + We need to flush the pending RBR event, since it keeps a + pointer to an open table. + + ALTERNATIVE SOLUTION (not implemented): Extract a pointer to + the pending RBR event and reset the table pointer after the + tables has been reopened. + + NOTE: For this new scheme there should be no pending event: + need to add code to assert that is the case. + */ + thd->binlog_flush_pending_rows_event(false); + TABLE_LIST *tables= rli->tables_to_lock; + close_tables_for_reopen(thd, &tables); + + uint tables_count= rli->tables_to_lock_count; + if ((error= open_tables(thd, &tables, &tables_count, 0))) + { + if (thd->is_slave_error || thd->is_fatal_error) + { + /* + Error reporting borrowed from Query_log_event with many excessive + simplifications (we don't honour --slave-skip-errors) + */ + uint actual_error= thd->net.client_last_errno; + rli->report(ERROR_LEVEL, actual_error, + "Error '%s' on reopening tables", + (actual_error ? thd->net.client_last_error : + "unexpected success or fatal error")); + thd->is_slave_error= 1; + } + const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); + DBUG_RETURN(error); + } + } + + /* + When the open and locking succeeded, we check all tables to + ensure that they still have the correct type. + + We can use a down cast here since we know that every table added + to the tables_to_lock is a RPL_TABLE_LIST. + */ + + { + RPL_TABLE_LIST *ptr= rli->tables_to_lock; + for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global)) + { + if (ptr->m_tabledef.compatible_with(rli, ptr->table)) + { + mysql_unlock_tables(thd, thd->lock); + thd->lock= 0; + thd->is_slave_error= 1; + const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); + DBUG_RETURN(ERR_BAD_TABLE_DEF); + } + } + } + + /* + ... and then we add all the tables to the table map and remove + them from tables to lock. + + We also invalidate the query cache for all the tables, since + they will now be changed. + + TODO [/Matz]: Maybe the query cache should not be invalidated + here? It might be that a table is not changed, even though it + was locked for the statement. We do know that each + Old_rows_log_event contain at least one row, so after processing one + Old_rows_log_event, we can invalidate the query cache for the + associated table. + */ + for (TABLE_LIST *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global) + { + const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table); + } +#ifdef HAVE_QUERY_CACHE + query_cache.invalidate_locked_for_write(rli->tables_to_lock); +#endif + } + + TABLE* + table= + m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id); + + if (table) + { + /* + table == NULL means that this table should not be replicated + (this was set up by Table_map_log_event::do_apply_event() + which tested replicate-* rules). + */ + + /* + It's not needed to set_time() but + 1) it continues the property that "Time" in SHOW PROCESSLIST shows how + much slave is behind + 2) it will be needed when we allow replication from a table with no + TIMESTAMP column to a table with one. + So we call set_time(), like in SBR. Presently it changes nothing. + */ + thd->set_time((time_t)when); + /* + There are a few flags that are replicated with each row event. + Make sure to set/clear them before executing the main body of + the event. + */ + if (get_flags(NO_FOREIGN_KEY_CHECKS_F)) + thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS; + else + thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS; + + if (get_flags(RELAXED_UNIQUE_CHECKS_F)) + thd->options|= OPTION_RELAXED_UNIQUE_CHECKS; + else + thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS; + /* A small test to verify that objects have consistent types */ + DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS)); + + /* + Now we are in a statement and will stay in a statement until we + see a STMT_END_F. + + We set this flag here, before actually applying any rows, in + case the SQL thread is stopped and we need to detect that we're + inside a statement and halting abruptly might cause problems + when restarting. + */ + const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT); + + if ( m_width == table->s->fields && bitmap_is_set_all(&m_cols)) + set_flags(COMPLETE_ROWS_F); + + /* + Set tables write and read sets. + + Read_set contains all slave columns (in case we are going to fetch + a complete record from slave) + + Write_set equals the m_cols bitmap sent from master but it can be + longer if slave has extra columns. + */ + + DBUG_PRINT_BITSET("debug", "Setting table's write_set from: %s", &m_cols); + + bitmap_set_all(table->read_set); + bitmap_set_all(table->write_set); + if (!get_flags(COMPLETE_ROWS_F)) + bitmap_intersect(table->write_set,&m_cols); + + // Do event specific preparations + + error= do_before_row_operations(rli); + + // row processing loop + + while (error == 0 && m_curr_row < m_rows_end) + { + /* in_use can have been set to NULL in close_tables_for_reopen */ + THD* old_thd= table->in_use; + if (!table->in_use) + table->in_use= thd; + + error= do_exec_row(rli); + + table->in_use = old_thd; + switch (error) + { + case 0: + break; + + /* Some recoverable errors */ + case HA_ERR_RECORD_CHANGED: + case HA_ERR_KEY_NOT_FOUND: /* Idempotency support: OK if + tuple does not exist */ + error= 0; + break; + + default: + rli->report(ERROR_LEVEL, thd->net.client_last_errno, + "Error in %s event: row application failed. %s", + get_type_str(), + thd->net.client_last_error ? thd->net.client_last_error : ""); + thd->is_slave_error= 1; + break; + } + + /* + If m_curr_row_end was not set during event execution (e.g., because + of errors) we can't proceed to the next row. If the error is transient + (i.e., error==0 at this point) we must call unpack_current_row() to set + m_curr_row_end. + */ + + DBUG_PRINT("info", ("error: %d", error)); + DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu", + (ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end)); + + if (!m_curr_row_end && !error) + unpack_current_row(rli); + + // at this moment m_curr_row_end should be set + DBUG_ASSERT(error || m_curr_row_end != NULL); + DBUG_ASSERT(error || m_curr_row < m_curr_row_end); + DBUG_ASSERT(error || m_curr_row_end <= m_rows_end); + + m_curr_row= m_curr_row_end; + + } // row processing loop + + DBUG_EXECUTE_IF("STOP_SLAVE_after_first_Rows_event", + const_cast<Relay_log_info*>(rli)->abort_slave= 1;); + error= do_after_row_operations(rli, error); + if (!cache_stmt) + { + DBUG_PRINT("info", ("Marked that we need to keep log")); + thd->options|= OPTION_KEEP_LOG; + } + } // if (table) + + /* + We need to delay this clear until here bacause unpack_current_row() uses + master-side table definitions stored in rli. + */ + if (rli->tables_to_lock && get_flags(STMT_END_F)) + const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); + + if (error) + { /* error has occured during the transaction */ + rli->report(ERROR_LEVEL, thd->net.client_last_errno, + "Error in %s event: error during transaction execution " + "on table %s.%s. %s", + get_type_str(), table->s->db.str, + table->s->table_name.str, + thd->net.client_last_error ? thd->net.client_last_error : ""); + + /* + If one day we honour --skip-slave-errors in row-based replication, and + the error should be skipped, then we would clear mappings, rollback, + close tables, but the slave SQL thread would not stop and then may + assume the mapping is still available, the tables are still open... + So then we should clear mappings/rollback/close here only if this is a + STMT_END_F. + For now we code, knowing that error is not skippable and so slave SQL + thread is certainly going to stop. + rollback at the caller along with sbr. + */ + thd->reset_current_stmt_binlog_row_based(); + const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error); + thd->is_slave_error= 1; + DBUG_RETURN(error); + } + + /* + This code would ideally be placed in do_update_pos() instead, but + since we have no access to table there, we do the setting of + last_event_start_time here instead. + */ + if (table && (table->s->primary_key == MAX_KEY) && + !cache_stmt && get_flags(STMT_END_F) == RLE_NO_FLAGS) + { + /* + ------------ Temporary fix until WL#2975 is implemented --------- + + This event is not the last one (no STMT_END_F). If we stop now + (in case of terminate_slave_thread()), how will we restart? We + have to restart from Table_map_log_event, but as this table is + not transactional, the rows already inserted will still be + present, and idempotency is not guaranteed (no PK) so we risk + that repeating leads to double insert. So we desperately try to + continue, hope we'll eventually leave this buggy situation (by + executing the final Old_rows_log_event). If we are in a hopeless + wait (reached end of last relay log and nothing gets appended + there), we timeout after one minute, and notify DBA about the + problem. When WL#2975 is implemented, just remove the member + Relay_log_info::last_event_start_time and all its occurrences. + */ + const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0); + } + + DBUG_RETURN(0); +} + + +Log_event::enum_skip_reason +Old_rows_log_event::do_shall_skip(Relay_log_info *rli) +{ + /* + If the slave skip counter is 1 and this event does not end a + statement, then we should not start executing on the next event. + Otherwise, we defer the decision to the normal skipping logic. + */ + if (rli->slave_skip_counter == 1 && !get_flags(STMT_END_F)) + return Log_event::EVENT_SKIP_IGNORE; + else + return Log_event::do_shall_skip(rli); +} + +int +Old_rows_log_event::do_update_pos(Relay_log_info *rli) +{ + DBUG_ENTER("Old_rows_log_event::do_update_pos"); + int error= 0; + + DBUG_PRINT("info", ("flags: %s", + get_flags(STMT_END_F) ? "STMT_END_F " : "")); + + if (get_flags(STMT_END_F)) + { + /* + This is the end of a statement or transaction, so close (and + unlock) the tables we opened when processing the + Table_map_log_event starting the statement. + + OBSERVER. This will clear *all* mappings, not only those that + are open for the table. There is not good handle for on-close + actions for tables. + + NOTE. Even if we have no table ('table' == 0) we still need to be + here, so that we increase the group relay log position. If we didn't, we + could have a group relay log position which lags behind "forever" + (assume the last master's transaction is ignored by the slave because of + replicate-ignore rules). + */ + thd->binlog_flush_pending_rows_event(true); + + /* + If this event is not in a transaction, the call below will, if some + transactional storage engines are involved, commit the statement into + them and flush the pending event to binlog. + If this event is in a transaction, the call will do nothing, but a + Xid_log_event will come next which will, if some transactional engines + are involved, commit the transaction and flush the pending event to the + binlog. + */ + error= ha_autocommit_or_rollback(thd, 0); + + /* + Now what if this is not a transactional engine? we still need to + flush the pending event to the binlog; we did it with + thd->binlog_flush_pending_rows_event(). Note that we imitate + what is done for real queries: a call to + ha_autocommit_or_rollback() (sometimes only if involves a + transactional engine), and a call to be sure to have the pending + event flushed. + */ + + thd->reset_current_stmt_binlog_row_based(); + rli->cleanup_context(thd, 0); + if (error == 0) + { + /* + Indicate that a statement is finished. + Step the group log position if we are not in a transaction, + otherwise increase the event log position. + */ + rli->stmt_done(log_pos, when); + + /* + Clear any errors pushed in thd->net.client_last_err* if for + example "no key found" (as this is allowed). This is a safety + measure; apparently those errors (e.g. when executing a + Delete_rows_log_event_old of a non-existing row, like in + rpl_row_mystery22.test, thd->net.client_last_error = "Can't + find record in 't1'" and last_errno=1032) do not become + visible. We still prefer to wipe them out. + */ + thd->clear_error(); + } + else + rli->report(ERROR_LEVEL, error, + "Error in %s event: commit of row events failed, " + "table `%s`.`%s`", + get_type_str(), m_table->s->db.str, + m_table->s->table_name.str); + } + else + { + rli->inc_event_relay_log_pos(); + } + + DBUG_RETURN(error); +} + +#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */ + + +#ifndef MYSQL_CLIENT +bool Old_rows_log_event::write_data_header(IO_CACHE *file) +{ + uchar buf[ROWS_HEADER_LEN]; // No need to init the buffer + + // This method should not be reached. + assert(0); + + DBUG_ASSERT(m_table_id != ~0UL); + DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", + { + int4store(buf + 0, m_table_id); + int2store(buf + 4, m_flags); + return (my_b_safe_write(file, buf, 6)); + }); + int6store(buf + RW_MAPID_OFFSET, (ulonglong)m_table_id); + int2store(buf + RW_FLAGS_OFFSET, m_flags); + return (my_b_safe_write(file, buf, ROWS_HEADER_LEN)); +} + + +bool Old_rows_log_event::write_data_body(IO_CACHE*file) +{ + /* + Note that this should be the number of *bits*, not the number of + bytes. + */ + uchar sbuf[sizeof(m_width)]; + my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf; + + // This method should not be reached. + assert(0); + + bool res= false; + uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width); + DBUG_ASSERT(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf)); + + DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf)); + res= res || my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf)); + + DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols)); + res= res || my_b_safe_write(file, (uchar*) m_cols.bitmap, + no_bytes_in_map(&m_cols)); + DBUG_DUMP("rows", m_rows_buf, data_size); + res= res || my_b_safe_write(file, m_rows_buf, (size_t) data_size); + + return res; + +} +#endif + + +#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) +void Old_rows_log_event::pack_info(Protocol *protocol) +{ + char buf[256]; + char const *const flagstr= + get_flags(STMT_END_F) ? " flags: STMT_END_F" : ""; + size_t bytes= my_snprintf(buf, sizeof(buf), + "table_id: %lu%s", m_table_id, flagstr); + protocol->store(buf, bytes, &my_charset_bin); +} +#endif + + +#ifdef MYSQL_CLIENT +void Old_rows_log_event::print_helper(FILE *file, + PRINT_EVENT_INFO *print_event_info, + char const *const name) +{ + IO_CACHE *const head= &print_event_info->head_cache; + IO_CACHE *const body= &print_event_info->body_cache; + if (!print_event_info->short_form) + { + bool const last_stmt_event= get_flags(STMT_END_F); + print_header(head, print_event_info, !last_stmt_event); + my_b_printf(head, "\t%s: table id %lu%s\n", + name, m_table_id, + last_stmt_event ? " flags: STMT_END_F" : ""); + print_base64(body, print_event_info, !last_stmt_event); + } + + if (get_flags(STMT_END_F)) + { + copy_event_cache_to_file_and_reinit(head, file); + copy_event_cache_to_file_and_reinit(body, file); + } +} +#endif + + +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) +/** + Write the current row into event's table. + + The row is located in the row buffer, pointed by @c m_curr_row member. + Number of columns of the row is stored in @c m_width member (it can be + different from the number of columns in the table to which we insert). + Bitmap @c m_cols indicates which columns are present in the row. It is assumed + that event's table is already open and pointed by @c m_table. + + If the same record already exists in the table it can be either overwritten + or an error is reported depending on the value of @c overwrite flag + (error reporting not yet implemented). Note that the matching record can be + different from the row we insert if we use primary keys to identify records in + the table. + + The row to be inserted can contain values only for selected columns. The + missing columns are filled with default values using @c prepare_record() + function. If a matching record is found in the table and @c overwritte is + true, the missing columns are taken from it. + + @param rli Relay log info (needed for row unpacking). + @param overwrite + Shall we overwrite if the row already exists or signal + error (currently ignored). + + @returns Error code on failure, 0 on success. + + This method, if successful, sets @c m_curr_row_end pointer to point at the + next row in the rows buffer. This is done when unpacking the row to be + inserted. + + @note If a matching record is found, it is either updated using + @c ha_update_row() or first deleted and then new record written. +*/ + +int +Old_rows_log_event::write_row(const Relay_log_info *const rli, + const bool overwrite) +{ + DBUG_ENTER("write_row"); + DBUG_ASSERT(m_table != NULL && thd != NULL); + + TABLE *table= m_table; // pointer to event's table + int error; + int keynum; + auto_afree_ptr<char> key(NULL); + + /* fill table->record[0] with default values */ + + if ((error= prepare_record(rli, table, m_width, + TRUE /* check if columns have def. values */))) + DBUG_RETURN(error); + + /* unpack row into table->record[0] */ + error= unpack_current_row(rli); // TODO: how to handle errors? + +#ifndef DBUG_OFF + DBUG_DUMP("record[0]", table->record[0], table->s->reclength); + DBUG_PRINT_BITSET("debug", "write_set = %s", table->write_set); + DBUG_PRINT_BITSET("debug", "read_set = %s", table->read_set); +#endif + + /* + Try to write record. If a corresponding record already exists in the table, + we try to change it using ha_update_row() if possible. Otherwise we delete + it and repeat the whole process again. + + TODO: Add safety measures against infinite looping. + */ + + while ((error= table->file->ha_write_row(table->record[0]))) + { + if (error == HA_ERR_LOCK_DEADLOCK || error == HA_ERR_LOCK_WAIT_TIMEOUT) + { + table->file->print_error(error, MYF(0)); /* to check at exec_relay_log_event */ + DBUG_RETURN(error); + } + if ((keynum= table->file->get_dup_key(error)) < 0) + { + DBUG_PRINT("info",("Can't locate duplicate key (get_dup_key returns %d)",keynum)); + table->file->print_error(error, MYF(0)); + /* + We failed to retrieve the duplicate key + - either because the error was not "duplicate key" error + - or because the information which key is not available + */ + DBUG_RETURN(error); + } + + /* + We need to retrieve the old row into record[1] to be able to + either update or delete the offending record. We either: + + - use rnd_pos() with a row-id (available as dupp_row) to the + offending row, if that is possible (MyISAM and Blackhole), or else + + - use index_read_idx() with the key that is duplicated, to + retrieve the offending row. + */ + if (table->file->ha_table_flags() & HA_DUPLICATE_POS) + { + DBUG_PRINT("info",("Locating offending record using rnd_pos()")); + error= table->file->rnd_pos(table->record[1], table->file->dup_ref); + if (error) + { + DBUG_PRINT("info",("rnd_pos() returns error %d",error)); + table->file->print_error(error, MYF(0)); + DBUG_RETURN(error); + } + } + else + { + DBUG_PRINT("info",("Locating offending record using index_read_idx()")); + + if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) + { + DBUG_PRINT("info",("Error when setting HA_EXTRA_FLUSH_CACHE")); + DBUG_RETURN(my_errno); + } + + if (key.get() == NULL) + { + key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length))); + if (key.get() == NULL) + { + DBUG_PRINT("info",("Can't allocate key buffer")); + DBUG_RETURN(ENOMEM); + } + } + + key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum, + 0); + error= table->file->index_read_idx_map(table->record[1], keynum, + (const uchar*)key.get(), + HA_WHOLE_KEY, + HA_READ_KEY_EXACT); + if (error) + { + DBUG_PRINT("info",("index_read_idx() returns error %d",error)); + table->file->print_error(error, MYF(0)); + DBUG_RETURN(error); + } + } + + /* + Now, record[1] should contain the offending row. That + will enable us to update it or, alternatively, delete it (so + that we can insert the new row afterwards). + */ + + /* + If row is incomplete we will use the record found to fill + missing columns. + */ + if (!get_flags(COMPLETE_ROWS_F)) + { + restore_record(table,record[1]); + error= unpack_current_row(rli); + } + +#ifndef DBUG_OFF + DBUG_PRINT("debug",("preparing for update: before and after image")); + DBUG_DUMP("record[1] (before)", table->record[1], table->s->reclength); + DBUG_DUMP("record[0] (after)", table->record[0], table->s->reclength); +#endif + + /* + REPLACE is defined as either INSERT or DELETE + INSERT. If + possible, we can replace it with an UPDATE, but that will not + work on InnoDB if FOREIGN KEY checks are necessary. + + I (Matz) am not sure of the reason for the last_uniq_key() + check as, but I'm guessing that it's something along the + following lines. + + Suppose that we got the duplicate key to be a key that is not + the last unique key for the table and we perform an update: + then there might be another key for which the unique check will + fail, so we're better off just deleting the row and inserting + the correct row. + */ + if (last_uniq_key(table, keynum) && + !table->file->referenced_by_foreign_key()) + { + DBUG_PRINT("info",("Updating row using ha_update_row()")); + error=table->file->ha_update_row(table->record[1], + table->record[0]); + switch (error) { + + case HA_ERR_RECORD_IS_THE_SAME: + DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from" + " ha_update_row()")); + error= 0; + + case 0: + break; + + default: + DBUG_PRINT("info",("ha_update_row() returns error %d",error)); + table->file->print_error(error, MYF(0)); + } + + DBUG_RETURN(error); + } + else + { + DBUG_PRINT("info",("Deleting offending row and trying to write new one again")); + if ((error= table->file->ha_delete_row(table->record[1]))) + { + DBUG_PRINT("info",("ha_delete_row() returns error %d",error)); + table->file->print_error(error, MYF(0)); + DBUG_RETURN(error); + } + /* Will retry ha_write_row() with the offending row removed. */ + } + } + + DBUG_RETURN(error); +} + + +/** + Locate the current row in event's table. + + The current row is pointed by @c m_curr_row. Member @c m_width tells how many + columns are there in the row (this can be differnet from the number of columns + in the table). It is assumed that event's table is already open and pointed + by @c m_table. + + If a corresponding record is found in the table it is stored in + @c m_table->record[0]. Note that when record is located based on a primary + key, it is possible that the record found differs from the row being located. + + If no key is specified or table does not have keys, a table scan is used to + find the row. In that case the row should be complete and contain values for + all columns. However, it can still be shorter than the table, i.e. the table + can contain extra columns not present in the row. It is also possible that + the table has fewer columns than the row being located. + + @returns Error code on failure, 0 on success. + + @post In case of success @c m_table->record[0] contains the record found. + Also, the internal "cursor" of the table is positioned at the record found. + + @note If the engine allows random access of the records, a combination of + @c position() and @c rnd_pos() will be used. + */ + +int Old_rows_log_event::find_row(const Relay_log_info *rli) +{ + DBUG_ENTER("find_row"); + + DBUG_ASSERT(m_table && m_table->in_use != NULL); + + TABLE *table= m_table; + int error; + + /* unpack row - missing fields get default values */ + + // TODO: shall we check and report errors here? + prepare_record(NULL,table,m_width,FALSE /* don't check errors */); + error= unpack_current_row(rli); + +#ifndef DBUG_OFF + DBUG_PRINT("info",("looking for the following record")); + DBUG_DUMP("record[0]", table->record[0], table->s->reclength); +#endif + + if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) && + table->s->primary_key < MAX_KEY) + { + /* + Use a more efficient method to fetch the record given by + table->record[0] if the engine allows it. We first compute a + row reference using the position() member function (it will be + stored in table->file->ref) and the use rnd_pos() to position + the "cursor" (i.e., record[0] in this case) at the correct row. + + TODO: Add a check that the correct record has been fetched by + comparing with the original record. Take into account that the + record on the master and slave can be of different + length. Something along these lines should work: + + ADD>>> store_record(table,record[1]); + int error= table->file->rnd_pos(table->record[0], table->file->ref); + ADD>>> DBUG_ASSERT(memcmp(table->record[1], table->record[0], + table->s->reclength) == 0); + + */ + DBUG_PRINT("info",("locating record using primary key (position)")); + int error= table->file->rnd_pos_by_record(table->record[0]); + if (error) + { + DBUG_PRINT("info",("rnd_pos returns error %d",error)); + table->file->print_error(error, MYF(0)); + } + DBUG_RETURN(error); + } + + // We can't use position() - try other methods. + + /* + We need to retrieve all fields + TODO: Move this out from this function to main loop + */ + table->use_all_columns(); + + /* + Save copy of the record in table->record[1]. It might be needed + later if linear search is used to find exact match. + */ + store_record(table,record[1]); + + if (table->s->keys > 0) + { + DBUG_PRINT("info",("locating record using primary key (index_read)")); + + /* We have a key: search the table using the index */ + if (!table->file->inited && (error= table->file->ha_index_init(0, FALSE))) + { + DBUG_PRINT("info",("ha_index_init returns error %d",error)); + table->file->print_error(error, MYF(0)); + DBUG_RETURN(error); + } + + /* Fill key data for the row */ + + DBUG_ASSERT(m_key); + key_copy(m_key, table->record[0], table->key_info, 0); + + /* + Don't print debug messages when running valgrind since they can + trigger false warnings. + */ +#ifndef HAVE_purify + DBUG_DUMP("key data", m_key, table->key_info->key_length); +#endif + + /* + We need to set the null bytes to ensure that the filler bit are + all set when returning. There are storage engines that just set + the necessary bits on the bytes and don't set the filler bits + correctly. + */ + my_ptrdiff_t const pos= + table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0; + table->record[0][pos]= 0xFF; + + if ((error= table->file->index_read_map(table->record[0], m_key, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT))) + { + DBUG_PRINT("info",("no record matching the key found in the table")); + table->file->print_error(error, MYF(0)); + table->file->ha_index_end(); + DBUG_RETURN(error); + } + + /* + Don't print debug messages when running valgrind since they can + trigger false warnings. + */ +#ifndef HAVE_purify + DBUG_PRINT("info",("found first matching record")); + DBUG_DUMP("record[0]", table->record[0], table->s->reclength); +#endif + /* + Below is a minor "optimization". If the key (i.e., key number + 0) has the HA_NOSAME flag set, we know that we have found the + correct record (since there can be no duplicates); otherwise, we + have to compare the record with the one found to see if it is + the correct one. + + CAVEAT! This behaviour is essential for the replication of, + e.g., the mysql.proc table since the correct record *shall* be + found using the primary key *only*. There shall be no + comparison of non-PK columns to decide if the correct record is + found. I can see no scenario where it would be incorrect to + chose the row to change only using a PK or an UNNI. + */ + if (table->key_info->flags & HA_NOSAME) + { + table->file->ha_index_end(); + DBUG_RETURN(0); + } + + /* + In case key is not unique, we still have to iterate over records found + and find the one which is identical to the row given. A copy of the + record we are looking for is stored in record[1]. + */ + DBUG_PRINT("info",("non-unique index, scanning it to find matching record")); + + while (record_compare(table)) + { + /* + We need to set the null bytes to ensure that the filler bit + are all set when returning. There are storage engines that + just set the necessary bits on the bytes and don't set the + filler bits correctly. + + TODO[record format ndb]: Remove this code once NDB returns the + correct record format. + */ + if (table->s->null_bytes > 0) + { + table->record[0][table->s->null_bytes - 1]|= + 256U - (1U << table->s->last_null_bit_pos); + } + + if ((error= table->file->index_next(table->record[0]))) + { + DBUG_PRINT("info",("no record matching the given row found")); + table->file->print_error(error, MYF(0)); + table->file->ha_index_end(); + DBUG_RETURN(error); + } + } + + /* + Have to restart the scan to be able to fetch the next row. + */ + table->file->ha_index_end(); + } + else + { + DBUG_PRINT("info",("locating record using table scan (rnd_next)")); + + int restart_count= 0; // Number of times scanning has restarted from top + + /* We don't have a key: search the table using rnd_next() */ + if ((error= table->file->ha_rnd_init(1))) + { + DBUG_PRINT("info",("error initializing table scan" + " (ha_rnd_init returns %d)",error)); + table->file->print_error(error, MYF(0)); + DBUG_RETURN(error); + } + + /* Continue until we find the right record or have made a full loop */ + do + { + error= table->file->rnd_next(table->record[0]); + + switch (error) { + + case 0: + case HA_ERR_RECORD_DELETED: + break; + + case HA_ERR_END_OF_FILE: + if (++restart_count < 2) + table->file->ha_rnd_init(1); + break; + + default: + DBUG_PRINT("info", ("Failed to get next record" + " (rnd_next returns %d)",error)); + table->file->print_error(error, MYF(0)); + table->file->ha_rnd_end(); + DBUG_RETURN(error); + } + } + while (restart_count < 2 && record_compare(table)); + + /* + Note: above record_compare will take into accout all record fields + which might be incorrect in case a partial row was given in the event + */ + + /* + Have to restart the scan to be able to fetch the next row. + */ + if (restart_count == 2) + DBUG_PRINT("info", ("Record not found")); + else + DBUG_DUMP("record found", table->record[0], table->s->reclength); + table->file->ha_rnd_end(); + + DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == 0); + DBUG_RETURN(error); + } + + DBUG_RETURN(0); +} + +#endif + + +/************************************************************************** + Write_rows_log_event member functions +**************************************************************************/ + +/* + Constructor used to build an event for writing to the binary log. + */ +#if !defined(MYSQL_CLIENT) +Write_rows_log_event_old::Write_rows_log_event_old(THD *thd_arg, + TABLE *tbl_arg, + ulong tid_arg, + MY_BITMAP const *cols, + bool is_transactional) + : Old_rows_log_event(thd_arg, tbl_arg, tid_arg, cols, is_transactional) +{ + + // This constructor should not be reached. + assert(0); + +} +#endif + + +/* + Constructor used by slave to read the event from the binary log. + */ +#ifdef HAVE_REPLICATION +Write_rows_log_event_old::Write_rows_log_event_old(const char *buf, + uint event_len, + const Format_description_log_event + *description_event) +: Old_rows_log_event(buf, event_len, PRE_GA_WRITE_ROWS_EVENT, + description_event) +{ +} +#endif + + +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) +int +Write_rows_log_event_old::do_before_row_operations(const Slave_reporting_capability *const) +{ + int error= 0; + + /* + We are using REPLACE semantics and not INSERT IGNORE semantics + when writing rows, that is: new rows replace old rows. We need to + inform the storage engine that it should use this behaviour. + */ + + /* Tell the storage engine that we are using REPLACE semantics. */ + thd->lex->duplicates= DUP_REPLACE; + + /* + Pretend we're executing a REPLACE command: this is needed for + InnoDB and NDB Cluster since they are not (properly) checking the + lex->duplicates flag. + */ + thd->lex->sql_command= SQLCOM_REPLACE; + /* + Do not raise the error flag in case of hitting to an unique attribute + */ + m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); + /* + NDB specific: update from ndb master wrapped as Write_rows + */ + /* + so that the event should be applied to replace slave's row + */ + m_table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE); + /* + NDB specific: if update from ndb master wrapped as Write_rows + does not find the row it's assumed idempotent binlog applying + is taking place; don't raise the error. + */ + m_table->file->extra(HA_EXTRA_IGNORE_NO_KEY); + /* + TODO: the cluster team (Tomas?) says that it's better if the engine knows + how many rows are going to be inserted, then it can allocate needed memory + from the start. + */ + m_table->file->ha_start_bulk_insert(0); + /* + We need TIMESTAMP_NO_AUTO_SET otherwise ha_write_row() will not use fill + any TIMESTAMP column with data from the row but instead will use + the event's current time. + As we replicate from TIMESTAMP to TIMESTAMP and slave has no extra + columns, we know that all TIMESTAMP columns on slave will receive explicit + data from the row, so TIMESTAMP_NO_AUTO_SET is ok. + When we allow a table without TIMESTAMP to be replicated to a table having + more columns including a TIMESTAMP column, or when we allow a TIMESTAMP + column to be replicated into a BIGINT column and the slave's table has a + TIMESTAMP column, then the slave's TIMESTAMP column will take its value + from set_time() which we called earlier (consistent with SBR). And then in + some cases we won't want TIMESTAMP_NO_AUTO_SET (will require some code to + analyze if explicit data is provided for slave's TIMESTAMP columns). + */ + m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; + return error; +} + + +int +Write_rows_log_event_old::do_after_row_operations(const Slave_reporting_capability *const, + int error) +{ + int local_error= 0; + m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); + m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); + /* + reseting the extra with + table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY); + fires bug#27077 + todo: explain or fix + */ + if ((local_error= m_table->file->ha_end_bulk_insert())) + { + m_table->file->print_error(local_error, MYF(0)); + } + return error? error : local_error; +} + + +int +Write_rows_log_event_old::do_exec_row(const Relay_log_info *const rli) +{ + DBUG_ASSERT(m_table != NULL); + int error= write_row(rli, TRUE /* overwrite */); + + if (error && !thd->net.client_last_errno) + thd->net.client_last_errno= error; + + return error; +} + +#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */ + + +#ifdef MYSQL_CLIENT +void Write_rows_log_event_old::print(FILE *file, + PRINT_EVENT_INFO* print_event_info) +{ + Old_rows_log_event::print_helper(file, print_event_info, "Write_rows_old"); +} +#endif + + +/************************************************************************** + Delete_rows_log_event member functions +**************************************************************************/ + +/* + Constructor used to build an event for writing to the binary log. + */ + +#ifndef MYSQL_CLIENT +Delete_rows_log_event_old::Delete_rows_log_event_old(THD *thd_arg, + TABLE *tbl_arg, + ulong tid, + MY_BITMAP const *cols, + bool is_transactional) + : Old_rows_log_event(thd_arg, tbl_arg, tid, cols, is_transactional), + m_after_image(NULL), m_memory(NULL) +{ + + // This constructor should not be reached. + assert(0); + +} +#endif /* #if !defined(MYSQL_CLIENT) */ + + +/* + Constructor used by slave to read the event from the binary log. + */ +#ifdef HAVE_REPLICATION +Delete_rows_log_event_old::Delete_rows_log_event_old(const char *buf, + uint event_len, + const Format_description_log_event + *description_event) + : Old_rows_log_event(buf, event_len, PRE_GA_DELETE_ROWS_EVENT, + description_event), + m_after_image(NULL), m_memory(NULL) +{ +} +#endif + + +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + +int +Delete_rows_log_event_old::do_before_row_operations(const Slave_reporting_capability *const) +{ + if ((m_table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) && + m_table->s->primary_key < MAX_KEY) + { + /* + We don't need to allocate any memory for m_key since it is not used. + */ + return 0; + } + + if (m_table->s->keys > 0) + { + // Allocate buffer for key searches + m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME)); + if (!m_key) + return HA_ERR_OUT_OF_MEM; + } + return 0; +} + + +int +Delete_rows_log_event_old::do_after_row_operations(const Slave_reporting_capability *const, + int error) +{ + /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/ + m_table->file->ha_index_or_rnd_end(); + my_free(m_key, MYF(MY_ALLOW_ZERO_PTR)); + m_key= NULL; + + return error; +} + + +int Delete_rows_log_event_old::do_exec_row(const Relay_log_info *const rli) +{ + int error; + DBUG_ASSERT(m_table != NULL); + + if (!(error= find_row(rli))) + { + /* + Delete the record found, located in record[0] + */ + error= m_table->file->ha_delete_row(m_table->record[0]); + } + return error; +} + +#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */ + + +#ifdef MYSQL_CLIENT +void Delete_rows_log_event_old::print(FILE *file, + PRINT_EVENT_INFO* print_event_info) +{ + Old_rows_log_event::print_helper(file, print_event_info, "Delete_rows_old"); +} +#endif + + +/************************************************************************** + Update_rows_log_event member functions +**************************************************************************/ + +/* + Constructor used to build an event for writing to the binary log. + */ +#if !defined(MYSQL_CLIENT) +Update_rows_log_event_old::Update_rows_log_event_old(THD *thd_arg, + TABLE *tbl_arg, + ulong tid, + MY_BITMAP const *cols, + bool is_transactional) + : Old_rows_log_event(thd_arg, tbl_arg, tid, cols, is_transactional), + m_after_image(NULL), m_memory(NULL) +{ + + // This constructor should not be reached. + assert(0); +} +#endif /* !defined(MYSQL_CLIENT) */ + + +/* + Constructor used by slave to read the event from the binary log. + */ +#ifdef HAVE_REPLICATION +Update_rows_log_event_old::Update_rows_log_event_old(const char *buf, + uint event_len, + const + Format_description_log_event + *description_event) + : Old_rows_log_event(buf, event_len, PRE_GA_UPDATE_ROWS_EVENT, + description_event), + m_after_image(NULL), m_memory(NULL) +{ +} +#endif + + +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + +int +Update_rows_log_event_old::do_before_row_operations(const Slave_reporting_capability *const) +{ + if (m_table->s->keys > 0) + { + // Allocate buffer for key searches + m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME)); + if (!m_key) + return HA_ERR_OUT_OF_MEM; + } + + m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; + + return 0; +} + + +int +Update_rows_log_event_old::do_after_row_operations(const Slave_reporting_capability *const, + int error) +{ + /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/ + m_table->file->ha_index_or_rnd_end(); + my_free(m_key, MYF(MY_ALLOW_ZERO_PTR)); // Free for multi_malloc + m_key= NULL; + + return error; +} + + +int +Update_rows_log_event_old::do_exec_row(const Relay_log_info *const rli) +{ + DBUG_ASSERT(m_table != NULL); + + int error= find_row(rli); + if (error) + { + /* + We need to read the second image in the event of error to be + able to skip to the next pair of updates + */ + m_curr_row= m_curr_row_end; + unpack_current_row(rli); + return error; + } + + /* + This is the situation after locating BI: + + ===|=== before image ====|=== after image ===|=== + ^ ^ + m_curr_row m_curr_row_end + + BI found in the table is stored in record[0]. We copy it to record[1] + and unpack AI to record[0]. + */ + + store_record(m_table,record[1]); + + m_curr_row= m_curr_row_end; + error= unpack_current_row(rli); // this also updates m_curr_row_end + + /* + Now we have the right row to update. The old row (the one we're + looking for) is in record[1] and the new row is in record[0]. + */ +#ifndef HAVE_purify + /* + Don't print debug messages when running valgrind since they can + trigger false warnings. + */ + DBUG_PRINT("info",("Updating row in table")); + DBUG_DUMP("old record", m_table->record[1], m_table->s->reclength); + DBUG_DUMP("new values", m_table->record[0], m_table->s->reclength); +#endif + + error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]); + if (error == HA_ERR_RECORD_IS_THE_SAME) + error= 0; + + return error; +} + +#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */ + + +#ifdef MYSQL_CLIENT +void Update_rows_log_event_old::print(FILE *file, + PRINT_EVENT_INFO* print_event_info) +{ + Old_rows_log_event::print_helper(file, print_event_info, "Update_rows_old"); +} +#endif diff --git a/sql/log_event_old.h b/sql/log_event_old.h index 4ae0b00aeac..719802a80fb 100644 --- a/sql/log_event_old.h +++ b/sql/log_event_old.h @@ -20,18 +20,261 @@ Need to include this file at the proper position of log_event.h */ + +/** + @file + + @brief This file contains classes handling old formats of row-based + binlog events. +*/ +/* + Around 2007-10-31, I made these classes completely separated from + the new classes (before, there was a complex class hierarchy + involving multiple inheritance; see BUG#31581), by simply copying + and pasting the entire contents of Rows_log_event into + Old_rows_log_event and the entire contents of + {Write|Update|Delete}_rows_log_event into + {Write|Update|Delete}_rows_log_event_old. For clarity, I will keep + the comments marking which code was cut-and-pasted for some time. + With the classes collapsed into one, there is probably some + redundancy (maybe some methods can be simplified and/or removed), + but we keep them this way for now. /Sven +*/ + + +/** + @class Old_rows_log_event -class Old_rows_log_event + Base class for the three types of row-based events + {Write|Update|Delete}_row_log_event_old, with event type codes + PRE_GA_{WRITE|UPDATE|DELETE}_ROWS_EVENT. These events are never + created any more, except when reading a relay log created by an old + server. +*/ +class Old_rows_log_event : public Log_event { - public: - - virtual ~Old_rows_log_event() {} + /********** BEGIN CUT & PASTE FROM Rows_log_event **********/ +public: + /** + Enumeration of the errors that can be returned. + */ + enum enum_error + { + ERR_OPEN_FAILURE = -1, /**< Failure to open table */ + ERR_OK = 0, /**< No error */ + ERR_TABLE_LIMIT_EXCEEDED = 1, /**< No more room for tables */ + ERR_OUT_OF_MEM = 2, /**< Out of memory */ + ERR_BAD_TABLE_DEF = 3, /**< Table definition does not match */ + ERR_RBR_TO_SBR = 4 /**< daisy-chanining RBR to SBR not allowed */ + }; + + /* + These definitions allow you to combine the flags into an + appropriate flag set using the normal bitwise operators. The + implicit conversion from an enum-constant to an integer is + accepted by the compiler, which is then used to set the real set + of flags. + */ + enum enum_flag + { + /* Last event of a statement */ + STMT_END_F = (1U << 0), + + /* Value of the OPTION_NO_FOREIGN_KEY_CHECKS flag in thd->options */ + NO_FOREIGN_KEY_CHECKS_F = (1U << 1), + + /* Value of the OPTION_RELAXED_UNIQUE_CHECKS flag in thd->options */ + RELAXED_UNIQUE_CHECKS_F = (1U << 2), + + /** + Indicates that rows in this event are complete, that is contain + values for all columns of the table. + */ + COMPLETE_ROWS_F = (1U << 3) + }; + + typedef uint16 flag_set; + + /* Special constants representing sets of flags */ + enum + { + RLE_NO_FLAGS = 0U + }; + + virtual ~Old_rows_log_event(); + + void set_flags(flag_set flags_arg) { m_flags |= flags_arg; } + void clear_flags(flag_set flags_arg) { m_flags &= ~flags_arg; } + flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; } + +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + virtual void pack_info(Protocol *protocol); +#endif + +#ifdef MYSQL_CLIENT + /* not for direct call, each derived has its own ::print() */ + virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0; +#endif + +#ifndef MYSQL_CLIENT + int add_row_data(uchar *data, size_t length) + { + return do_add_row_data(data,length); + } +#endif + + /* Member functions to implement superclass interface */ + virtual int get_data_size(); + + MY_BITMAP const *get_cols() const { return &m_cols; } + size_t get_width() const { return m_width; } + ulong get_table_id() const { return m_table_id; } + +#ifndef MYSQL_CLIENT + virtual bool write_data_header(IO_CACHE *file); + virtual bool write_data_body(IO_CACHE *file); + virtual const char *get_db() { return m_table->s->db.str; } +#endif + /* + Check that malloc() succeeded in allocating memory for the rows + buffer and the COLS vector. Checking that an Update_rows_log_event_old + is valid is done in the Update_rows_log_event_old::is_valid() + function. + */ + virtual bool is_valid() const + { + return m_rows_buf && m_cols.bitmap; + } + + uint m_row_count; /* The number of rows added to the event */ + +protected: + /* + The constructors are protected since you're supposed to inherit + this class, not create instances of this class. + */ +#ifndef MYSQL_CLIENT + Old_rows_log_event(THD*, TABLE*, ulong table_id, + MY_BITMAP const *cols, bool is_transactional); +#endif + Old_rows_log_event(const char *row_data, uint event_len, + Log_event_type event_type, + const Format_description_log_event *description_event); + +#ifdef MYSQL_CLIENT + void print_helper(FILE *, PRINT_EVENT_INFO *, char const *const name); +#endif + +#ifndef MYSQL_CLIENT + virtual int do_add_row_data(uchar *data, size_t length); +#endif + +#ifndef MYSQL_CLIENT + TABLE *m_table; /* The table the rows belong to */ +#endif + ulong m_table_id; /* Table ID */ + MY_BITMAP m_cols; /* Bitmap denoting columns available */ + ulong m_width; /* The width of the columns bitmap */ + + ulong m_master_reclength; /* Length of record on master side */ + + /* Bit buffers in the same memory as the class */ + uint32 m_bitbuf[128/(sizeof(uint32)*8)]; + uint32 m_bitbuf_ai[128/(sizeof(uint32)*8)]; + + uchar *m_rows_buf; /* The rows in packed format */ + uchar *m_rows_cur; /* One-after the end of the data */ + uchar *m_rows_end; /* One-after the end of the allocated space */ + + flag_set m_flags; /* Flags for row-level events */ + + /* helper functions */ + +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + const uchar *m_curr_row; /* Start of the row being processed */ + const uchar *m_curr_row_end; /* One-after the end of the current row */ + uchar *m_key; /* Buffer to keep key value during searches */ + + int find_row(const Relay_log_info *const); + int write_row(const Relay_log_info *const, const bool); + + // Unpack the current row into m_table->record[0] + int unpack_current_row(const Relay_log_info *const rli) + { + DBUG_ASSERT(m_table); + ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT); + int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols, + &m_curr_row_end, &m_master_reclength); + ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT); + return result; + } +#endif + +private: + +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + virtual int do_apply_event(Relay_log_info const *rli); + virtual int do_update_pos(Relay_log_info *rli); + virtual enum_skip_reason do_shall_skip(Relay_log_info *rli); + + /* + Primitive to prepare for a sequence of row executions. + + DESCRIPTION + + Before doing a sequence of do_prepare_row() and do_exec_row() + calls, this member function should be called to prepare for the + entire sequence. Typically, this member function will allocate + space for any buffers that are needed for the two member + functions mentioned above. + + RETURN VALUE + + The member function will return 0 if all went OK, or a non-zero + error code otherwise. + */ + virtual + int do_before_row_operations(const Slave_reporting_capability *const log) = 0; + + /* + Primitive to clean up after a sequence of row executions. + + DESCRIPTION + + After doing a sequence of do_prepare_row() and do_exec_row(), + this member function should be called to clean up and release + any allocated buffers. + + The error argument, if non-zero, indicates an error which happened during + row processing before this function was called. In this case, even if + function is successful, it should return the error code given in the argument. + */ + virtual + int do_after_row_operations(const Slave_reporting_capability *const log, + int error) = 0; + + /* + Primitive to do the actual execution necessary for a row. + + DESCRIPTION + The member function will do the actual execution needed to handle a row. + The row is located at m_curr_row. When the function returns, + m_curr_row_end should point at the next row (one byte after the end + of the current row). + + RETURN VALUE + 0 if execution succeeded, 1 if execution failed. + + */ + virtual int do_exec_row(const Relay_log_info *const rli) = 0; +#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */ + /********** END OF CUT & PASTE FROM Rows_log_event **********/ protected: #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) - int do_apply_event(Rows_log_event*,const Relay_log_info*); + int do_apply_event(Old_rows_log_event*,const Relay_log_info*); /* Primitive to prepare for a sequence of row executions. @@ -100,33 +343,61 @@ class Old_rows_log_event }; -class Write_rows_log_event_old - : public Write_rows_log_event, public Old_rows_log_event -{ +/** + @class Write_rows_log_event_old + Old class for binlog events that write new rows to a table (event + type code PRE_GA_WRITE_ROWS_EVENT). Such events are never produced + by this version of the server, but they may be read from a relay log + created by an old server. New servers create events of class + Write_rows_log_event (event type code WRITE_ROWS_EVENT) instead. +*/ +class Write_rows_log_event_old : public Old_rows_log_event +{ + /********** BEGIN CUT & PASTE FROM Write_rows_log_event **********/ public: - enum - { - /* Support interface to THD::binlog_prepare_pending_rows_event */ - TYPE_CODE = PRE_GA_WRITE_ROWS_EVENT - }; - #if !defined(MYSQL_CLIENT) - Write_rows_log_event_old(THD *thd_arg, TABLE *table, ulong table_id, - MY_BITMAP const *cols, bool is_transactional) - : Write_rows_log_event(thd_arg, table, table_id, cols, is_transactional) - { - } + Write_rows_log_event_old(THD*, TABLE*, ulong table_id, + MY_BITMAP const *cols, bool is_transactional); #endif -#if defined(HAVE_REPLICATION) +#ifdef HAVE_REPLICATION Write_rows_log_event_old(const char *buf, uint event_len, - const Format_description_log_event *descr) - : Write_rows_log_event(buf, event_len, descr) + const Format_description_log_event *description_event); +#endif +#if !defined(MYSQL_CLIENT) + static bool binlog_row_logging_function(THD *thd, TABLE *table, + bool is_transactional, + MY_BITMAP *cols, + uint fields, + const uchar *before_record + __attribute__((unused)), + const uchar *after_record) { + return thd->binlog_write_row(table, is_transactional, + cols, fields, after_record); } #endif private: +#ifdef MYSQL_CLIENT + void print(FILE *file, PRINT_EVENT_INFO *print_event_info); +#endif + +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + virtual int do_before_row_operations(const Slave_reporting_capability *const); + virtual int do_after_row_operations(const Slave_reporting_capability *const,int); + virtual int do_exec_row(const Relay_log_info *const); +#endif + /********** END OF CUT & PASTE FROM Write_rows_log_event **********/ + +public: + enum + { + /* Support interface to THD::binlog_prepare_pending_rows_event */ + TYPE_CODE = PRE_GA_WRITE_ROWS_EVENT + }; + +private: virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; } #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) @@ -145,9 +416,56 @@ private: }; -class Update_rows_log_event_old - : public Update_rows_log_event, public Old_rows_log_event +/** + @class Update_rows_log_event_old + + Old class for binlog events that modify existing rows to a table + (event type code PRE_GA_UPDATE_ROWS_EVENT). Such events are never + produced by this version of the server, but they may be read from a + relay log created by an old server. New servers create events of + class Update_rows_log_event (event type code UPDATE_ROWS_EVENT) + instead. +*/ +class Update_rows_log_event_old : public Old_rows_log_event { + /********** BEGIN CUT & PASTE FROM Update_rows_log_event **********/ +public: +#ifndef MYSQL_CLIENT + Update_rows_log_event_old(THD*, TABLE*, ulong table_id, + MY_BITMAP const *cols, + bool is_transactional); +#endif + +#ifdef HAVE_REPLICATION + Update_rows_log_event_old(const char *buf, uint event_len, + const Format_description_log_event *description_event); +#endif + +#if !defined(MYSQL_CLIENT) + static bool binlog_row_logging_function(THD *thd, TABLE *table, + bool is_transactional, + MY_BITMAP *cols, + uint fields, + const uchar *before_record, + const uchar *after_record) + { + return thd->binlog_update_row(table, is_transactional, + cols, fields, before_record, after_record); + } +#endif + +protected: +#ifdef MYSQL_CLIENT + void print(FILE *file, PRINT_EVENT_INFO *print_event_info); +#endif + +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + virtual int do_before_row_operations(const Slave_reporting_capability *const); + virtual int do_after_row_operations(const Slave_reporting_capability *const,int); + virtual int do_exec_row(const Relay_log_info *const); +#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */ + /********** END OF CUT & PASTE FROM Update_rows_log_event **********/ + uchar *m_after_image, *m_memory; public: @@ -157,23 +475,6 @@ public: TYPE_CODE = PRE_GA_UPDATE_ROWS_EVENT }; -#if !defined(MYSQL_CLIENT) - Update_rows_log_event_old(THD *thd_arg, TABLE *table, ulong table_id, - MY_BITMAP const *cols, bool is_transactional) - : Update_rows_log_event(thd_arg, table, table_id, cols, is_transactional), - m_after_image(NULL), m_memory(NULL) - { - } -#endif -#if defined(HAVE_REPLICATION) - Update_rows_log_event_old(const char *buf, uint event_len, - const Format_description_log_event *descr) - : Update_rows_log_event(buf, event_len, descr), - m_after_image(NULL), m_memory(NULL) - { - } -#endif - private: virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; } @@ -192,9 +493,54 @@ private: }; -class Delete_rows_log_event_old - : public Delete_rows_log_event, public Old_rows_log_event +/** + @class Delete_rows_log_event_old + + Old class for binlog events that delete existing rows from a table + (event type code PRE_GA_DELETE_ROWS_EVENT). Such events are never + produced by this version of the server, but they may be read from a + relay log created by an old server. New servers create events of + class Delete_rows_log_event (event type code DELETE_ROWS_EVENT) + instead. +*/ +class Delete_rows_log_event_old : public Old_rows_log_event { + /********** BEGIN CUT & PASTE FROM Update_rows_log_event **********/ +public: +#ifndef MYSQL_CLIENT + Delete_rows_log_event_old(THD*, TABLE*, ulong, + MY_BITMAP const *cols, bool is_transactional); +#endif +#ifdef HAVE_REPLICATION + Delete_rows_log_event_old(const char *buf, uint event_len, + const Format_description_log_event *description_event); +#endif +#if !defined(MYSQL_CLIENT) + static bool binlog_row_logging_function(THD *thd, TABLE *table, + bool is_transactional, + MY_BITMAP *cols, + uint fields, + const uchar *before_record, + const uchar *after_record + __attribute__((unused))) + { + return thd->binlog_delete_row(table, is_transactional, + cols, fields, before_record); + } +#endif + +protected: +#ifdef MYSQL_CLIENT + void print(FILE *file, PRINT_EVENT_INFO *print_event_info); +#endif + +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + virtual int do_before_row_operations(const Slave_reporting_capability *const); + virtual int do_after_row_operations(const Slave_reporting_capability *const,int); + virtual int do_exec_row(const Relay_log_info *const); +#endif + /********** END CUT & PASTE FROM Delete_rows_log_event **********/ + uchar *m_after_image, *m_memory; public: @@ -204,23 +550,6 @@ public: TYPE_CODE = PRE_GA_DELETE_ROWS_EVENT }; -#if !defined(MYSQL_CLIENT) - Delete_rows_log_event_old(THD *thd_arg, TABLE *table, ulong table_id, - MY_BITMAP const *cols, bool is_transactional) - : Delete_rows_log_event(thd_arg, table, table_id, cols, is_transactional), - m_after_image(NULL), m_memory(NULL) - { - } -#endif -#if defined(HAVE_REPLICATION) - Delete_rows_log_event_old(const char *buf, uint event_len, - const Format_description_log_event *descr) - : Delete_rows_log_event(buf, event_len, descr), - m_after_image(NULL), m_memory(NULL) - { - } -#endif - private: virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; } @@ -240,4 +569,3 @@ private: #endif - diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index cb12e50e054..3f83d577707 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1880,6 +1880,7 @@ extern uint volatile thread_count, thread_running, global_read_lock; extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types; extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap; extern my_bool opt_slave_compressed_protocol, use_temp_pool; +extern ulong slave_exec_mode_options; extern my_bool opt_readonly, lower_case_file_system; extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs; extern my_bool opt_secure_auth; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 56c5734146c..03783e56a9f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -461,6 +461,8 @@ ulong what_to_log; ulong query_buff_size, slow_launch_time, slave_open_temp_tables; ulong open_files_limit, max_binlog_size, max_relay_log_size; ulong slave_net_timeout, slave_trans_retries; +ulong slave_exec_mode_options; +const char *slave_exec_mode_str= "STRICT"; ulong thread_cache_size=0, thread_pool_size= 0; ulong binlog_cache_size=0, max_binlog_cache_size=0; ulong query_cache_size=0; @@ -610,7 +612,10 @@ char *opt_logname, *opt_slow_logname; /* Static variables */ static bool kill_in_progress, segfaulted; -static my_bool opt_do_pstack, opt_bootstrap, opt_myisam_log; +#ifdef HAVE_STACK_TRACE_ON_SEGV +static my_bool opt_do_pstack; +#endif /* HAVE_STACK_TRACE_ON_SEGV */ +static my_bool opt_bootstrap, opt_myisam_log; static int cleanup_done; static ulong opt_specialflag, opt_myisam_block_size; static char *opt_update_logname, *opt_binlog_index_name; @@ -5335,7 +5340,8 @@ enum options_mysqld OPT_SECURE_FILE_PRIV, OPT_MIN_EXAMINED_ROW_LIMIT, OPT_LOG_SLOW_SLAVE_STATEMENTS, - OPT_DEBUG_CRC, OPT_DEBUG_ON, OPT_OLD_MODE + OPT_DEBUG_CRC, OPT_DEBUG_ON, OPT_OLD_MODE, + OPT_SLAVE_EXEC_MODE }; @@ -5514,9 +5520,11 @@ struct my_option my_long_options[] = (uchar**) &opt_enable_named_pipe, (uchar**) &opt_enable_named_pipe, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif +#ifdef HAVE_STACK_TRACE_ON_SEGV {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure.", (uchar**) &opt_do_pstack, (uchar**) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, +#endif /* HAVE_STACK_TRACE_ON_SEGV */ {"engine-condition-pushdown", OPT_ENGINE_CONDITION_PUSHDOWN, "Push supported query conditions to the storage engine.", @@ -6044,8 +6052,11 @@ replicating a LOAD DATA INFILE command.", (uchar**) &slave_load_tmpdir, (uchar**) &slave_load_tmpdir, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"slave-skip-errors", OPT_SLAVE_SKIP_ERRORS, - "Tells the slave thread to continue replication when a query returns an error from the provided list.", + "Tells the slave thread to continue replication when a query event returns an error from the provided list.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"slave-exec-mode", OPT_SLAVE_EXEC_MODE, + "Modes for how replication events should be executed. Legal values are STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode, replication will not stop for operations that are idempotent. In STRICT mode, replication will stop on any unexpected difference between the master and the slave.", + (uchar**) &slave_exec_mode_str, (uchar**) &slave_exec_mode_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif {"slow-query-log", OPT_SLOW_LOG, "Enable|disable slow query log", (uchar**) &opt_slow_log, @@ -7254,6 +7265,9 @@ static void mysql_init_variables(void) /* Things with default values that are not zero */ delay_key_write_options= (uint) DELAY_KEY_WRITE_ON; + slave_exec_mode_options= 0; + slave_exec_mode_options= (uint) + find_bit_type_or_exit(slave_exec_mode_str, &slave_exec_mode_typelib, NULL); opt_specialflag= SPECIAL_ENGLISH; unix_sock= ip_sock= INVALID_SOCKET; mysql_home_ptr= mysql_home; @@ -7467,6 +7481,10 @@ mysqld_get_one_option(int optid, case OPT_SLAVE_SKIP_ERRORS: init_slave_skip_errors(argument); break; + case OPT_SLAVE_EXEC_MODE: + slave_exec_mode_options= (uint) + find_bit_type_or_exit(argument, &slave_exec_mode_typelib, ""); + break; #endif case OPT_SAFEMALLOC_MEM_LIMIT: #if !defined(DBUG_OFF) && defined(SAFEMALLOC) @@ -8017,6 +8035,8 @@ static void get_options(int *argc,char **argv) } /* Set global MyISAM variables from delay_key_write_options */ fix_delay_key_write((THD*) 0, OPT_GLOBAL); + /* Set global slave_exec_mode from its option */ + fix_slave_exec_mode(OPT_GLOBAL); #ifndef EMBEDDED_LIBRARY if (mysqld_chroot) diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index d33c81b55e8..589ee8b2605 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -946,7 +946,7 @@ bool load_master_data(THD* thd) 0, (SLAVE_IO | SLAVE_SQL))) my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0)); strmake(active_mi->master_log_name, row[0], - sizeof(active_mi->master_log_name)); + sizeof(active_mi->master_log_name) -1); active_mi->master_log_pos= my_strtoll10(row[1], (char**) 0, &error_2); /* at least in recent versions, the condition below should be false */ if (active_mi->master_log_pos < BIN_LOG_HEADER_SIZE) diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 3467f6fd67c..3e9a484126a 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -33,6 +33,7 @@ Relay_log_info::Relay_log_info() :Slave_reporting_capability("SQL"), no_storage(FALSE), replicate_same_server_id(::replicate_same_server_id), info_fd(-1), cur_log_fd(-1), save_temporary_tables(0), + group_relay_log_pos(0), cur_log_old_open_count(0), group_master_log_pos(0), log_space_total(0), ignore_log_space_limit(0), last_master_timestamp(0), slave_skip_counter(0), abort_pos_wait(0), slave_run_id(0), sql_thd(0), @@ -1160,6 +1161,11 @@ void Relay_log_info::cleanup_context(THD *thd, bool error) close_thread_tables(thd); clear_tables_to_lock(); clear_flag(IN_STMT); + /* + Cleanup for the flags that have been set at do_apply_event. + */ + thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS; + thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS; last_event_start_time= 0; DBUG_VOID_RETURN; } diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index b3ca26d4c2c..4f4083d9b8f 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -164,7 +164,7 @@ uint32 table_def::calc_field_size(uint col, uchar *master_data) const break; } default: - length= -1; + length= ~(uint32) 0; } return length; } diff --git a/sql/set_var.cc b/sql/set_var.cc index 144abbb9a2d..fcdd36dc0f6 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -93,6 +93,16 @@ TYPELIB delay_key_write_typelib= delay_key_write_type_names, NULL }; +const char *slave_exec_mode_names[]= +{ "STRICT", "IDEMPOTENT", NullS }; +static const unsigned int slave_exec_mode_names_len[]= +{ sizeof("STRICT") - 1, sizeof("IDEMPOTENT") - 1, 0 }; +TYPELIB slave_exec_mode_typelib= +{ + array_elements(slave_exec_mode_names)-1, "", + slave_exec_mode_names, (unsigned int *) slave_exec_mode_names_len +}; + static int sys_check_ftb_syntax(THD *thd, set_var *var); static bool sys_update_ftb_syntax(THD *thd, set_var * var); static void sys_default_ftb_syntax(THD *thd, enum_var_type type); @@ -417,6 +427,11 @@ static sys_var_const_str_ptr sys_secure_file_priv(&vars, "secure_file_priv", static sys_var_long_ptr sys_server_id(&vars, "server_id", &server_id, fix_server_id); static sys_var_bool_ptr sys_slave_compressed_protocol(&vars, "slave_compressed_protocol", &opt_slave_compressed_protocol); +static sys_var_set_slave_mode slave_exec_mode(&vars, + "slave_exec_mode", + &slave_exec_mode_options, + &slave_exec_mode_typelib, + 0); static sys_var_long_ptr sys_slow_launch_time(&vars, "slow_launch_time", &slow_launch_time); static sys_var_thd_ulong sys_sort_buffer(&vars, "sort_buffer_size", @@ -1003,6 +1018,79 @@ extern void fix_delay_key_write(THD *thd, enum_var_type type) } } +bool sys_var_set::update(THD *thd, set_var *var) +{ + *value= var->save_result.ulong_value; + return 0; +}; + +uchar *sys_var_set::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + char buff[256]; + String tmp(buff, sizeof(buff), &my_charset_latin1); + ulong length; + ulong val= *value; + + tmp.length(0); + for (uint i= 0; val; val>>= 1, i++) + { + if (val & 1) + { + tmp.append(enum_names->type_names[i], + enum_names->type_lengths[i]); + tmp.append(','); + } + } + + if ((length= tmp.length())) + length--; + return (uchar*) thd->strmake(tmp.ptr(), length); +} + +void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type) +{ + slave_exec_mode_options= 0; + bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT); +} + +bool sys_var_set_slave_mode::check(THD *thd, set_var *var) +{ + bool rc= sys_var_set::check(thd, var); + if (!rc && + bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_STRICT) == 1 && + bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_IDEMPOTENT) == 1) + { + rc= true; + my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), ""); + } + return rc; +} + +bool sys_var_set_slave_mode::update(THD *thd, set_var *var) +{ + bool rc; + pthread_mutex_lock(&LOCK_global_system_variables); + rc= sys_var_set::update(thd, var); + pthread_mutex_unlock(&LOCK_global_system_variables); + return rc; +} + +void fix_slave_exec_mode(enum_var_type type) +{ + DBUG_ENTER("fix_slave_exec_mode"); + compile_time_assert(sizeof(slave_exec_mode_options) * CHAR_BIT + > SLAVE_EXEC_MODE_LAST_BIT - 1); + if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT) == 1 && + bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 1) + { + sql_print_error("Ambiguous slave modes combination." + " STRICT will be used"); + bit_do_clear(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT); + } + if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0) + bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT); +} bool sys_var_thd_binlog_format::is_readonly() const { @@ -1116,6 +1204,7 @@ static void fix_trans_mem_root(THD *thd, enum_var_type type) static void fix_server_id(THD *thd, enum_var_type type) { server_id_supplied = 1; + thd->server_id= server_id; } @@ -3280,7 +3369,18 @@ int set_var::light_check(THD *thd) return 0; } +/** + Update variable + @param thd thread handler + @returns 0|1 ok or ERROR + + @note ERROR can be only due to abnormal operations involving + the server's execution evironment such as + out of memory, hard disk failure or the computer blows up. + Consider set_var::check() method if there is a need to return + an error due to logics. +*/ int set_var::update(THD *thd) { if (!value) diff --git a/sql/set_var.h b/sql/set_var.h index 723b31eb188..634bb67760e 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -30,7 +30,8 @@ class sys_var_pluginvar; /* opaque */ typedef struct system_variables SV; typedef struct my_locale_st MY_LOCALE; -extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib; +extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib, + slave_exec_mode_typelib; typedef int (*sys_check_func)(THD *, set_var *); typedef bool (*sys_update_func)(THD *, set_var *); @@ -804,6 +805,42 @@ public: }; +class sys_var_set :public sys_var +{ +protected: + ulong *value; + TYPELIB *enum_names; +public: + sys_var_set(sys_var_chain *chain, const char *name_arg, ulong *value_arg, + TYPELIB *typelib, sys_after_update_func func) + :sys_var(name_arg, func), value(value_arg), enum_names(typelib) + { chain_sys_var(chain); } + virtual bool check(THD *thd, set_var *var) + { + return check_set(thd, var, enum_names); + } + virtual void set_default(THD *thd, enum_var_type type) + { + *value= 0; + } + bool update(THD *thd, set_var *var); + uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); + bool check_update_type(Item_result type) { return 0; } + SHOW_TYPE show_type() { return SHOW_CHAR; } +}; + +class sys_var_set_slave_mode :public sys_var_set +{ +public: + sys_var_set_slave_mode(sys_var_chain *chain, const char *name_arg, + ulong *value_arg, + TYPELIB *typelib, sys_after_update_func func) : + sys_var_set(chain, name_arg, value_arg, typelib, func) {} + void set_default(THD *thd, enum_var_type type); + bool check(THD *thd, set_var *var); + bool update(THD *thd, set_var *var); +}; + class sys_var_log_output :public sys_var { ulong *value; @@ -1222,6 +1259,7 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length=0); int sql_set_variables(THD *thd, List<set_var_base> *var_list); bool not_all_support_one_shot(List<set_var_base> *var_list); void fix_delay_key_write(THD *thd, enum_var_type type); +void fix_slave_exec_mode(enum_var_type type); ulong fix_sql_mode(ulong sql_mode); extern sys_var_const_str sys_charset_system; extern sys_var_str sys_init_connect; diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 02e20ad7c5c..026a0023660 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -6114,3 +6114,8 @@ ER_TRG_CANT_OPEN_TABLE ER_CANT_CREATE_SROUTINE eng "Cannot create stored routine `%-.64s`. Check warnings" +ER_SLAVE_AMBIGOUS_EXEC_MODE + eng "Ambiguous slave modes combination. %s" + +ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT + eng "The BINLOG statement of type `%s` was not preceded by a format description BINLOG statement." diff --git a/sql/slave.cc b/sql/slave.cc index 45e3d4da090..4ffc2023e85 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -13,6 +13,17 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + @addtogroup Replication + @{ + + @file + + @brief Code to run the io thread and the sql thread on the + replication slave. +*/ + #include "mysql_priv.h" #include <mysql.h> @@ -33,10 +44,6 @@ #include "rpl_tblmap.h" -int queue_event(Master_info* mi,const char* buf,ulong event_len); -static Log_event* next_event(Relay_log_info* rli); - - #define FLAGSTR(V,F) ((V)&(F)?#F" ":"") #define MAX_SLAVE_RETRY_PAUSE 5 @@ -132,6 +139,7 @@ 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 Log_event* next_event(Relay_log_info* rli); +static int queue_event(Master_info* mi,const char* buf,ulong event_len); static int terminate_slave_thread(THD *thd, pthread_mutex_t* term_lock, pthread_cond_t* term_cond, @@ -1775,6 +1783,175 @@ static int has_temporary_error(THD *thd) DBUG_RETURN(0); } + +/** + Applies the given event and advances the relay log position. + + In essence, this function does: + + @code + ev->apply_event(rli); + ev->update_pos(rli); + @endcode + + But it also does some maintainance, such as skipping events if + needed and reporting errors. + + If the @c skip flag is set, then it is tested whether the event + should be skipped, by looking at the slave_skip_counter and the + server id. The skip flag should be set when calling this from a + replication thread but not set when executing an explicit BINLOG + statement. + + @retval 0 OK. + + @retval 1 Error calling ev->apply_event(). + + @retval 2 No error calling ev->apply_event(), but error calling + ev->update_pos(). +*/ +int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli, + bool skip) +{ + int exec_res= 0; + + DBUG_ENTER("apply_event_and_update_pos"); + + DBUG_PRINT("exec_event",("%s(type_code: %d; server_id: %d)", + ev->get_type_str(), ev->get_type_code(), + ev->server_id)); + DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu", + FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT), + FLAGSTR(thd->options, OPTION_BEGIN), + rli->last_event_start_time)); + + /* + Execute the event to change the database and update the binary + log coordinates, but first we set some data that is needed for + the thread. + + The event will be executed unless it is supposed to be skipped. + + Queries originating from this server must be skipped. Low-level + events (Format_description_log_event, Rotate_log_event, + Stop_log_event) from this server must also be skipped. But for + those we don't want to modify 'group_master_log_pos', because + these events did not exist on the master. + Format_description_log_event is not completely skipped. + + Skip queries specified by the user in 'slave_skip_counter'. We + can't however skip events that has something to do with the log + files themselves. + + Filtering on own server id is extremely important, to ignore + execution of events created by the creation/rotation of the relay + log (remember that now the relay log starts with its Format_desc, + has a Rotate etc). + */ + + thd->server_id = ev->server_id; // use the original server id for logging + thd->set_time(); // time the query + thd->lex->current_select= 0; + if (!ev->when) + ev->when= my_time(0); + ev->thd = thd; // because up to this point, ev->thd == 0 + + if (skip) + { + int reason= ev->shall_skip(rli); + if (reason == Log_event::EVENT_SKIP_COUNT) + --rli->slave_skip_counter; + pthread_mutex_unlock(&rli->data_lock); + if (reason == Log_event::EVENT_SKIP_NOT) + exec_res= ev->apply_event(rli); +#ifndef DBUG_OFF + /* + This only prints information to the debug trace. + + TODO: Print an informational message to the error log? + */ + static const char *const explain[] = { + // EVENT_SKIP_NOT, + "not skipped", + // EVENT_SKIP_IGNORE, + "skipped because event should be ignored", + // EVENT_SKIP_COUNT + "skipped because event skip counter was non-zero" + }; + DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d", + thd->options & OPTION_BEGIN ? 1 : 0, + rli->get_flag(Relay_log_info::IN_STMT))); + DBUG_PRINT("skip_event", ("%s event was %s", + ev->get_type_str(), explain[reason])); +#endif + } + else + exec_res= ev->apply_event(rli); + + DBUG_PRINT("info", ("apply_event error = %d", exec_res)); + if (exec_res == 0) + { + int error= ev->update_pos(rli); + char buf[22]; + DBUG_PRINT("info", ("update_pos error = %d", error)); + DBUG_PRINT("info", ("group %s %s", + llstr(rli->group_relay_log_pos, buf), + rli->group_relay_log_name)); + DBUG_PRINT("info", ("event %s %s", + llstr(rli->event_relay_log_pos, buf), + rli->event_relay_log_name)); + /* + The update should not fail, so print an error message and + return an error code. + + TODO: Replace this with a decent error message when merged + with BUG#24954 (which adds several new error message). + */ + if (error) + { + rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, + "It was not possible to update the positions" + " of the relay log information: the slave may" + " be in an inconsistent state." + " Stopped in %s position %s", + rli->group_relay_log_name, + llstr(rli->group_relay_log_pos, buf)); + DBUG_RETURN(2); + } + } + + DBUG_RETURN(exec_res ? 1 : 0); +} + + +/** + Top-level function for executing the next event from the relay log. + + This function reads the event from the relay log, executes it, and + advances the relay log position. It also handles errors, etc. + + This function may fail to apply the event for the following reasons: + + - The position specfied by the UNTIL condition of the START SLAVE + command is reached. + + - It was not possible to read the event from the log. + + - The slave is killed. + + - An error occurred when applying the event, and the event has been + tried slave_trans_retries times. If the event has been retried + fewer times, 0 is returned. + + - init_master_info or init_relay_log_pos failed. (These are called + if a failure occurs when applying the event.)</li> + + - An error occurred when updating the binlog position. + + @retval 0 The event was applied. + + @retval 1 The event was not applied. +*/ static int exec_relay_log_event(THD* thd, Relay_log_info* rli) { DBUG_ENTER("exec_relay_log_event"); @@ -1820,117 +1997,26 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli) } if (ev) { - int const type_code= ev->get_type_code(); - int exec_res= 0; - - DBUG_PRINT("exec_event",("%s(type_code: %d; server_id: %d)", - ev->get_type_str(), type_code, ev->server_id)); - DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu", - FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT), - FLAGSTR(thd->options, OPTION_BEGIN), - rli->last_event_start_time)); - + int exec_res= apply_event_and_update_pos(ev, thd, rli, TRUE); /* - Execute the event to change the database and update the binary - log coordinates, but first we set some data that is needed for - the thread. - - The event will be executed unless it is supposed to be skipped. - - Queries originating from this server must be skipped. Low-level - events (Format_description_log_event, Rotate_log_event, - Stop_log_event) from this server must also be skipped. But for - those we don't want to modify 'group_master_log_pos', because - these events did not exist on the master. - Format_description_log_event is not completely skipped. - - Skip queries specified by the user in 'slave_skip_counter'. We - can't however skip events that has something to do with the log - files themselves. - - Filtering on own server id is extremely important, to ignore - execution of events created by the creation/rotation of the relay - log (remember that now the relay log starts with its Format_desc, - has a Rotate etc). + Format_description_log_event should not be deleted because it will be + used to read info about the relay log's format; it will be deleted when + the SQL thread does not need it, i.e. when this thread terminates. */ - - thd->server_id = ev->server_id; // use the original server id for logging - thd->set_time(); // time the query - thd->lex->current_select= 0; - if (!ev->when) - ev->when= my_time(0); - ev->thd = thd; // because up to this point, ev->thd == 0 - - int reason= ev->shall_skip(rli); - if (reason == Log_event::EVENT_SKIP_COUNT) - --rli->slave_skip_counter; - pthread_mutex_unlock(&rli->data_lock); - if (reason == Log_event::EVENT_SKIP_NOT) - exec_res= ev->apply_event(rli); -#ifndef DBUG_OFF - /* - This only prints information to the debug trace. - - TODO: Print an informational message to the error log? - */ - static const char *const explain[] = { - // EVENT_SKIP_NOT, - "not skipped", - // EVENT_SKIP_IGNORE, - "skipped because event should be ignored", - // EVENT_SKIP_COUNT - "skipped because event skip counter was non-zero" - }; - DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d", - thd->options & OPTION_BEGIN ? 1 : 0, - rli->get_flag(Relay_log_info::IN_STMT))); - DBUG_PRINT("skip_event", ("%s event was %s", - ev->get_type_str(), explain[reason])); -#endif - - DBUG_PRINT("info", ("apply_event error = %d", exec_res)); - if (exec_res == 0) + if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT) { - int error= ev->update_pos(rli); - char buf[22]; - DBUG_PRINT("info", ("update_pos error = %d", error)); - DBUG_PRINT("info", ("group %s %s", - llstr(rli->group_relay_log_pos, buf), - rli->group_relay_log_name)); - DBUG_PRINT("info", ("event %s %s", - llstr(rli->event_relay_log_pos, buf), - rli->event_relay_log_name)); - /* - The update should not fail, so print an error message and - return an error code. - - TODO: Replace this with a decent error message when merged - with BUG#24954 (which adds several new error message). - */ - if (error) - { - rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, - "It was not possible to update the positions" - " of the relay log information: the slave may" - " be in an inconsistent state." - " Stopped in %s position %s", - rli->group_relay_log_name, - llstr(rli->group_relay_log_pos, buf)); - DBUG_RETURN(1); - } + DBUG_PRINT("info", ("Deleting the event after it has been executed")); + delete ev; } /* - Format_description_log_event should not be deleted because it will be - used to read info about the relay log's format; it will be deleted when - the SQL thread does not need it, i.e. when this thread terminates. + update_log_pos failed: this should not happen, so we don't + retry. */ - if (type_code != FORMAT_DESCRIPTION_EVENT) - { - DBUG_PRINT("info", ("Deleting the event after it has been executed")); - delete ev; - } + if (exec_res == 2) + DBUG_RETURN(1); + if (slave_trans_retries) { int temp_err; @@ -2760,7 +2846,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev) } if (unlikely(cev_not_written)) { - cev->block = (char*)net->read_pos; + cev->block = net->read_pos; cev->block_len = num_bytes; if (unlikely(mi->rli.relay_log.append(cev))) { @@ -2774,7 +2860,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev) } else { - aev.block = (char*)net->read_pos; + aev.block = net->read_pos; aev.block_len = num_bytes; aev.log_pos = cev->log_pos; if (unlikely(mi->rli.relay_log.append(&aev))) @@ -3074,7 +3160,7 @@ static int queue_old_event(Master_info *mi, const char *buf, any >=5.0.0 format. */ -int queue_event(Master_info* mi,const char* buf, ulong event_len) +static int queue_event(Master_info* mi,const char* buf, ulong event_len) { int error= 0; ulong inc_pos; @@ -3960,4 +4046,8 @@ template class I_List_iterator<i_string>; template class I_List_iterator<i_string_pair>; #endif +/** + @} (end of group Replication) +*/ + #endif /* HAVE_REPLICATION */ diff --git a/sql/slave.h b/sql/slave.h index 2cd9ea352ba..f1772bbc1fc 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -187,6 +187,8 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset, void set_slave_thread_options(THD* thd); void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli); void rotate_relay_log(Master_info* mi); +int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli, + bool skip); pthread_handler_t handle_slave_io(void *arg); pthread_handler_t handle_slave_sql(void *arg); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 4a0e18129ad..0edb566ed9f 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2120,11 +2120,17 @@ sp_head::backpatch(sp_label_t *lab) uint dest= instructions(); List_iterator_fast<bp_t> li(m_backpatch); + DBUG_ENTER("sp_head::backpatch"); while ((bp= li++)) { if (bp->lab == lab) + { + DBUG_PRINT("info", ("backpatch: (m_ip %d, label 0x%lx <%s>) to dest %d", + bp->instr->m_ip, (ulong) lab, lab->name, dest)); bp->instr->backpatch(dest, lab->ctx); + } } + DBUG_VOID_RETURN; } /** diff --git a/sql/sp_head.h b/sql/sp_head.h index 01a4cb73704..8d7062740c8 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -888,8 +888,9 @@ public: virtual void backpatch(uint dest, sp_pcontext *dst_ctx) { - if (m_dest == 0) // Don't reset - m_dest= dest; + /* Calling backpatch twice is a logic flaw in jump resolution. */ + DBUG_ASSERT(m_dest == 0); + m_dest= dest; } /** diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 8395648689b..9b237b3e7cc 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -314,17 +314,91 @@ sp_rcontext::handle_error(uint sql_errno, void sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i) { + DBUG_ENTER("sp_rcontext::push_cursor"); + DBUG_ASSERT(m_ccount < m_root_parsing_ctx->max_cursor_index()); m_cstack[m_ccount++]= new sp_cursor(lex_keeper, i); + DBUG_PRINT("info", ("m_ccount: %d", m_ccount)); + DBUG_VOID_RETURN; } - void sp_rcontext::pop_cursors(uint count) { + DBUG_ENTER("sp_rcontext::pop_cursors"); + DBUG_ASSERT(m_ccount >= count); while (count--) { delete m_cstack[--m_ccount]; } + DBUG_PRINT("info", ("m_ccount: %d", m_ccount)); + DBUG_VOID_RETURN; +} + +void +sp_rcontext::push_handler(struct sp_cond_type *cond, uint h, int type, uint f) +{ + DBUG_ENTER("sp_rcontext::push_handler"); + DBUG_ASSERT(m_hcount < m_root_parsing_ctx->max_handler_index()); + + m_handler[m_hcount].cond= cond; + m_handler[m_hcount].handler= h; + m_handler[m_hcount].type= type; + m_handler[m_hcount].foffset= f; + m_hcount+= 1; + + DBUG_PRINT("info", ("m_hcount: %d", m_hcount)); + DBUG_VOID_RETURN; +} + +void +sp_rcontext::pop_handlers(uint count) +{ + DBUG_ENTER("sp_rcontext::pop_handlers"); + DBUG_ASSERT(m_hcount >= count); + m_hcount-= count; + DBUG_PRINT("info", ("m_hcount: %d", m_hcount)); + DBUG_VOID_RETURN; +} + +void +sp_rcontext::push_hstack(uint h) +{ + DBUG_ENTER("sp_rcontext::push_hstack"); + DBUG_ASSERT(m_hsp < m_root_parsing_ctx->max_handler_index()); + m_hstack[m_hsp++]= h; + DBUG_PRINT("info", ("m_hsp: %d", m_hsp)); + DBUG_VOID_RETURN; +} + +uint +sp_rcontext::pop_hstack() +{ + uint handler; + DBUG_ENTER("sp_rcontext::pop_hstack"); + DBUG_ASSERT(m_hsp); + handler= m_hstack[--m_hsp]; + DBUG_PRINT("info", ("m_hsp: %d", m_hsp)); + DBUG_RETURN(handler); +} + +void +sp_rcontext::enter_handler(int hid) +{ + DBUG_ENTER("sp_rcontext::enter_handler"); + DBUG_ASSERT(m_ihsp < m_root_parsing_ctx->max_handler_index()); + m_in_handler[m_ihsp++]= hid; + DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp)); + DBUG_VOID_RETURN; +} + +void +sp_rcontext::exit_handler() +{ + DBUG_ENTER("sp_rcontext::exit_handler"); + DBUG_ASSERT(m_ihsp); + m_ihsp-= 1; + DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp)); + DBUG_VOID_RETURN; } diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index 43102cfeeb2..368a017da21 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -107,21 +107,9 @@ class sp_rcontext : public Sql_alloc return m_return_value_set; } - inline void - push_handler(struct sp_cond_type *cond, uint h, int type, uint f) - { - m_handler[m_hcount].cond= cond; - m_handler[m_hcount].handler= h; - m_handler[m_hcount].type= type; - m_handler[m_hcount].foffset= f; - m_hcount+= 1; - } + void push_handler(struct sp_cond_type *cond, uint h, int type, uint f); - inline void - pop_handlers(uint count) - { - m_hcount-= count; - } + void pop_handlers(uint count); // Returns 1 if a handler was found, 0 otherwise. bool @@ -158,29 +146,13 @@ class sp_rcontext : public Sql_alloc m_hfound= -1; } - inline void - push_hstack(uint h) - { - m_hstack[m_hsp++]= h; - } + void push_hstack(uint h); - inline uint - pop_hstack() - { - return m_hstack[--m_hsp]; - } + uint pop_hstack(); - inline void - enter_handler(int hid) - { - m_in_handler[m_ihsp++]= hid; - } + void enter_handler(int hid); - inline void - exit_handler() - { - m_ihsp-= 1; - } + void exit_handler(); void push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d2d26da229a..0d563ab9051 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5579,6 +5579,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list) LEX_USER *user_name, *tmp_user_name; List_iterator <LEX_USER> user_list(list); TABLE_LIST tables[GRANT_TABLES]; + bool some_users_created= FALSE; DBUG_ENTER("mysql_create_user"); /* @@ -5614,6 +5615,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list) continue; } + some_users_created= TRUE; sql_mode= thd->variables.sql_mode; if (replace_user_table(thd, tables[0].table, *user_name, 0, 0, 1, 0)) { @@ -5624,12 +5626,14 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list) VOID(pthread_mutex_unlock(&acl_cache->lock)); - write_bin_log(thd, FALSE, thd->query, thd->query_length); + if (result) + my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr_safe()); + + if (some_users_created) + write_bin_log(thd, FALSE, thd->query, thd->query_length); rw_unlock(&LOCK_grant); close_thread_tables(thd); - if (result) - my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr_safe()); DBUG_RETURN(result); } @@ -5654,6 +5658,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) LEX_USER *user_name, *tmp_user_name; List_iterator <LEX_USER> user_list(list); TABLE_LIST tables[GRANT_TABLES]; + bool some_users_deleted= FALSE; DBUG_ENTER("mysql_drop_user"); /* @@ -5682,7 +5687,9 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) { append_user(&wrong_users, user_name); result= TRUE; + continue; } + some_users_deleted= TRUE; } /* Rebuild 'acl_check_hosts' since 'acl_users' has been modified */ @@ -5693,7 +5700,8 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) if (result) my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe()); - write_bin_log(thd, FALSE, thd->query, thd->query_length); + if (some_users_deleted) + write_bin_log(thd, FALSE, thd->query, thd->query_length); rw_unlock(&LOCK_grant); close_thread_tables(thd); @@ -5722,6 +5730,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) LEX_USER *user_to, *tmp_user_to; List_iterator <LEX_USER> user_list(list); TABLE_LIST tables[GRANT_TABLES]; + bool some_users_renamed= FALSE; DBUG_ENTER("mysql_rename_user"); /* @@ -5762,7 +5771,9 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) { append_user(&wrong_users, user_from); result= TRUE; + continue; } + some_users_renamed= TRUE; } /* Rebuild 'acl_check_hosts' since 'acl_users' has been modified */ @@ -5770,12 +5781,14 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) VOID(pthread_mutex_unlock(&acl_cache->lock)); - write_bin_log(thd, FALSE, thd->query, thd->query_length); + if (result) + my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe()); + + if (some_users_renamed && mysql_bin_log.is_open()) + write_bin_log(thd, FALSE, thd->query, thd->query_length); rw_unlock(&LOCK_grant); close_thread_tables(thd); - if (result) - my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe()); DBUG_RETURN(result); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 9e4dceff87d..799cb673a0e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3934,7 +3934,7 @@ retry: READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, ha_open_options | HA_OPEN_FOR_REPAIR, entry, FALSE) || ! entry->file || - (entry->file->is_crashed() && entry->file->check_and_repair(thd))) + (entry->file->is_crashed() && entry->file->ha_check_and_repair(thd))) { /* Give right error message */ thd->clear_error(); @@ -5400,7 +5400,7 @@ bool rm_temporary_table(handlerton *base, char *path) error=1; /* purecov: inspected */ *ext= 0; // remove extension file= get_new_handler((TABLE_SHARE*) 0, current_thd->mem_root, base); - if (file && file->delete_table(path)) + if (file && file->ha_delete_table(path)) { error=1; sql_print_warning("Could not remove temporary table: '%s', error: %d", @@ -6400,7 +6400,36 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, *resolution= RESOLVED_IGNORING_ALIAS; break; } - } + } + else if (table_name && item->type() == Item::REF_ITEM && + ((Item_ref *)item)->ref_type() == Item_ref::VIEW_REF) + { + /* + TODO:Here we process prefixed view references only. What we should + really do is process all types of Item_refs. But this will currently + lead to a clash with the way references to outer SELECTs (from the + HAVING clause) are handled in e.g. : + SELECT 1 FROM t1 AS t1_o GROUP BY a + HAVING (SELECT t1_o.a FROM t1 AS t1_i GROUP BY t1_i.a LIMIT 1). + Processing all Item_refs here will cause t1_o.a to resolve to itself. + We still need to process the special case of Item_direct_view_ref + because in the context of views they have the same meaning as + Item_field for tables. + */ + Item_ident *item_ref= (Item_ident *) item; + if (item_ref->name && item_ref->table_name && + !my_strcasecmp(system_charset_info, item_ref->name, field_name) && + !my_strcasecmp(table_alias_charset, item_ref->table_name, + table_name) && + (!db_name || (item_ref->db_name && + !strcmp (item_ref->db_name, db_name)))) + { + found= li.ref(); + *counter= i; + *resolution= RESOLVED_IGNORING_ALIAS; + break; + } + } } if (!found) { @@ -8070,7 +8099,7 @@ my_bool mysql_rm_tmp_tables(void) ((handler_file= get_new_handler(&share, thd->mem_root, share.db_type())))) { - handler_file->delete_table(filePathCopy); + handler_file->ha_delete_table(filePathCopy); delete handler_file; } free_table_share(&share); diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc index 77c5155b41b..04f408453ea 100644 --- a/sql/sql_binlog.cc +++ b/sql/sql_binlog.cc @@ -17,15 +17,14 @@ #include "rpl_rli.h" #include "base64.h" -/* +/** Execute a BINLOG statement - TODO: This currently assumes a MySQL 5.x binlog. - When we'll have binlog with a different format, to execute the - BINLOG command properly the server will need to know which format - the BINLOG command's event is in. mysqlbinlog should then send - the Format_description_log_event of the binlog it reads and the - server thread should cache this format into + To execute the BINLOG command properly the server needs to know + which format the BINLOG command's event is in. Therefore, the first + BINLOG statement seen must be a base64 encoding of the + Format_description_log_event, as outputted by mysqlbinlog. This + Format_description_log_event is cached in rli->description_event_for_exec. */ @@ -47,11 +46,24 @@ void mysql_client_binlog_statement(THD* thd) /* Allocation */ + + /* + If we do not have a Format_description_event, we create a dummy + one here. In this case, the first event we read must be a + Format_description_event. + */ + my_bool have_fd_event= TRUE; if (!thd->rli_fake) + { thd->rli_fake= new Relay_log_info; - - const Format_description_log_event *desc= - new Format_description_log_event(4); + have_fd_event= FALSE; + } + if (thd->rli_fake && !thd->rli_fake->relay_log.description_event_for_exec) + { + thd->rli_fake->relay_log.description_event_for_exec= + new Format_description_log_event(4); + have_fd_event= FALSE; + } const char *error= 0; char *buf= (char *) my_malloc(decoded_len, MYF(MY_WME)); @@ -60,7 +72,9 @@ void mysql_client_binlog_statement(THD* thd) /* Out of memory check */ - if (!(thd->rli_fake && desc && buf)) + if (!(thd->rli_fake && + thd->rli_fake->relay_log.description_event_for_exec && + buf)) { my_error(ER_OUTOFMEMORY, MYF(0), 1); /* needed 1 bytes */ goto end; @@ -131,7 +145,28 @@ void mysql_client_binlog_statement(THD* thd) goto end; } - ev= Log_event::read_log_event(bufptr, event_len, &error, desc); + /* + If we have not seen any Format_description_event, then we must + see one; it is the only statement that can be read in base64 + without a prior Format_description_event. + */ + if (!have_fd_event) + { + if (bufptr[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) + have_fd_event= TRUE; + else + { + my_error(ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT, + MYF(0), + Log_event::get_type_str( + (Log_event_type)bufptr[EVENT_TYPE_OFFSET])); + goto end; + } + } + + ev= Log_event::read_log_event(bufptr, event_len, &error, + thd->rli_fake->relay_log. + description_event_for_exec); DBUG_PRINT("info",("binlog base64 err=%s", error)); if (!ev) @@ -167,11 +202,10 @@ void mysql_client_binlog_statement(THD* thd) Neither do we have to update the log positions, since that is not used at all: the rli_fake instance is used only for error reporting. - */ + */ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) - if (IF_DBUG(int err= ) ev->apply_event(thd->rli_fake)) + if (apply_event_and_update_pos(ev, thd, thd->rli_fake, FALSE)) { - DBUG_PRINT("info", ("apply_event() returned: %d", err)); /* TODO: Maybe a better error message since the BINLOG statement now contains several events. @@ -181,7 +215,14 @@ void mysql_client_binlog_statement(THD* thd) } #endif - delete ev; + /* + Format_description_log_event should not be deleted because it + will be used to read info about the relay log's format; it + will be deleted when the SQL thread does not need it, + i.e. when this thread terminates. + */ + if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT) + delete ev; ev= 0; } } @@ -191,7 +232,6 @@ void mysql_client_binlog_statement(THD* thd) send_ok(thd); end: - delete desc; my_free(buf, MYF(MY_ALLOW_ZERO_PTR)); DBUG_VOID_RETURN; } diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index e51c53f644e..7e54f87fe14 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -371,6 +371,32 @@ TODO list: __LINE__,(ulong)(B)));B->query()->unlock_reading();} #define DUMP(C) DBUG_EXECUTE("qcache", {\ (C)->cache_dump(); (C)->queries_dump();(C)->tables_dump();}) + + +/** + Causes the thread to wait in a spin lock for a query kill signal. + This function is used by the test frame work to identify race conditions. + + The signal is caught and ignored and the thread is not killed. +*/ + +static void debug_wait_for_kill(const char *info) +{ + DBUG_ENTER("debug_wait_for_kill"); + const char *prev_info; + THD *thd; + thd= current_thd; + prev_info= thd->proc_info; + thd->proc_info= info; + sql_print_information(info); + while(!thd->killed) + my_sleep(1000); + thd->killed= THD::NOT_KILLED; + sql_print_information("Exit debug_wait_for_kill"); + thd->proc_info= prev_info; + DBUG_VOID_RETURN; +} + #else #define MUTEX_LOCK(M) pthread_mutex_lock(M) #define MUTEX_UNLOCK(M) pthread_mutex_unlock(M) @@ -647,13 +673,16 @@ void query_cache_insert(NET *net, const char *packet, ulong length) if (net->query_cache_query == 0) DBUG_VOID_RETURN; + DBUG_EXECUTE_IF("wait_in_query_cache_insert", + debug_wait_for_kill("wait_in_query_cache_insert"); ); + STRUCT_LOCK(&query_cache.structure_guard_mutex); bool interrupt; query_cache.wait_while_table_flush_is_in_progress(&interrupt); if (interrupt) { STRUCT_UNLOCK(&query_cache.structure_guard_mutex); - return; + DBUG_VOID_RETURN; } Query_cache_block *query_block= (Query_cache_block*)net->query_cache_query; @@ -667,11 +696,11 @@ void query_cache_insert(NET *net, const char *packet, ulong length) DBUG_VOID_RETURN; } + BLOCK_LOCK_WR(query_block); Query_cache_query *header= query_block->query(); Query_cache_block *result= header->result(); DUMP(&query_cache); - BLOCK_LOCK_WR(query_block); DBUG_PRINT("qcache", ("insert packet %lu bytes long",length)); /* @@ -687,6 +716,7 @@ void query_cache_insert(NET *net, const char *packet, ulong length) DBUG_PRINT("qcache", ("free query 0x%lx", (ulong) query_block)); // The following call will remove the lock on query_block query_cache.free_query(query_block); + query_cache.refused++; // append_result_data no success => we need unlock STRUCT_UNLOCK(&query_cache.structure_guard_mutex); DBUG_VOID_RETURN; @@ -886,6 +916,31 @@ ulong Query_cache::resize(ulong query_cache_size_arg) m_cache_status= Query_cache::FLUSH_IN_PROGRESS; STRUCT_UNLOCK(&structure_guard_mutex); + /* + Wait for all readers and writers to exit. When the list of all queries + is iterated over with a block level lock, we are done. + */ + Query_cache_block *block= queries_blocks; + if (block) + { + do + { + BLOCK_LOCK_WR(block); + Query_cache_query *query= block->query(); + if (query && query->writer()) + { + /* + Drop the writer; this will cancel any attempts to store + the processed statement associated with this writer. + */ + query->writer()->query_cache_query= 0; + query->writer(0); + refused++; + } + BLOCK_UNLOCK_WR(block); + block= block->next; + } while (block != queries_blocks); + } free_cache(); query_cache_size= query_cache_size_arg; diff --git a/sql/sql_class.h b/sql/sql_class.h index 2342f7326a2..bda8ae43917 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -38,6 +38,9 @@ enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME }; enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE }; enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, DELAY_KEY_WRITE_ALL }; +enum enum_slave_exec_mode { SLAVE_EXEC_MODE_STRICT, + SLAVE_EXEC_MODE_IDEMPOTENT, + SLAVE_EXEC_MODE_LAST_BIT}; enum enum_mark_columns { MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE}; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index f158b5488d0..b5f49b97ec9 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -1396,7 +1396,7 @@ static void backup_current_db_name(THD *thd, } else { - strmake(saved_db_name->str, thd->db, saved_db_name->length); + strmake(saved_db_name->str, thd->db, saved_db_name->length - 1); saved_db_name->length= thd->db_length; } } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 1f6216efb2e..adaf4d537f1 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -123,7 +123,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); ha_rows const maybe_deleted= table->file->stats.records; DBUG_PRINT("debug", ("Trying to use delete_all_rows()")); - if (!(error=table->file->delete_all_rows())) + if (!(error=table->file->ha_delete_all_rows())) { error= -1; // ok deleted= maybe_deleted; @@ -328,7 +328,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, We're really doing a truncate and need to reset the table's auto-increment counter. */ - int error2= table->file->reset_auto_increment(0); + int error2= table->file->ha_reset_auto_increment(0); if (error2 && (error2 != HA_ERR_WRONG_COMMAND)) { diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 1dc256bb7c3..cb0728490b7 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -619,7 +619,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (mysql_prepare_insert(thd, table_list, table, fields, values, update_fields, update_values, duplic, &unused_conds, FALSE, - (fields.elements || !value_count), + (fields.elements || !value_count || + table_list->view != 0), !ignore && (thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)))) @@ -1862,7 +1863,6 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) { if (!(di= new Delayed_insert())) { - my_error(ER_OUTOFMEMORY,MYF(0),sizeof(Delayed_insert)); thd->fatal_error(); goto end_create; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a739ddcc194..25584797549 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1318,7 +1318,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, unregister_slave(thd,1,1); /* fake COM_QUIT -- if we get here, the thread needs to terminate */ error = TRUE; - net->error = 0; break; } #endif diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index ce70e177a85..eabf4526f7b 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -5108,9 +5108,9 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) DBUG_ENTER("mysql_change_partitions"); build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0); - if ((error= file->change_partitions(lpt->create_info, path, &lpt->copied, - &lpt->deleted, lpt->pack_frm_data, - lpt->pack_frm_len))) + if ((error= file->ha_change_partitions(lpt->create_info, path, &lpt->copied, + &lpt->deleted, lpt->pack_frm_data, + lpt->pack_frm_len))) { if (error != ER_OUTOFMEMORY) file->print_error(error, MYF(0)); @@ -5148,7 +5148,7 @@ static bool mysql_rename_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) DBUG_ENTER("mysql_rename_partitions"); build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0); - if ((error= lpt->table->file->rename_partitions(path))) + if ((error= lpt->table->file->ha_rename_partitions(path))) { if (error != 1) lpt->table->file->print_error(error, MYF(0)); @@ -5189,7 +5189,7 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) DBUG_ENTER("mysql_drop_partitions"); build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0); - if ((error= lpt->table->file->drop_partitions(path))) + if ((error= lpt->table->file->ha_drop_partitions(path))) { lpt->table->file->print_error(error, MYF(0)); DBUG_RETURN(TRUE); @@ -6105,13 +6105,13 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, int error; written_bin_log= FALSE; if (((alter_info->flags & ALTER_OPTIMIZE_PARTITION) && - (error= table->file->optimize_partitions(thd))) || + (error= table->file->ha_optimize_partitions(thd))) || ((alter_info->flags & ALTER_ANALYZE_PARTITION) && - (error= table->file->analyze_partitions(thd))) || + (error= table->file->ha_analyze_partitions(thd))) || ((alter_info->flags & ALTER_CHECK_PARTITION) && - (error= table->file->check_partitions(thd))) || + (error= table->file->ha_check_partitions(thd))) || ((alter_info->flags & ALTER_REPAIR_PARTITION) && - (error= table->file->repair_partitions(thd)))) + (error= table->file->ha_repair_partitions(thd)))) { table->file->print_error(error, MYF(0)); goto err; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 1e05e19c6f5..cdce2fa695b 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1243,9 +1243,6 @@ bool change_master(THD* thd, Master_info* mi) DBUG_RETURN(TRUE); } } - mi->rli.group_master_log_pos = mi->master_log_pos; - DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos)); - /* Coordinates in rli were spoilt by the 'if (need_relay_log_purge)' block, so restore them to good values. If we left them to ''/0, that would work; @@ -1257,6 +1254,7 @@ bool change_master(THD* thd, Master_info* mi) That's why we always save good coords in rli. */ mi->rli.group_master_log_pos= mi->master_log_pos; + DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos)); strmake(mi->rli.group_master_log_name,mi->master_log_name, sizeof(mi->rli.group_master_log_name)-1); @@ -1376,6 +1374,11 @@ bool mysql_show_binlog_events(THD* thd) if ((file=open_binlog(&log, linfo.log_file_name, &errmsg)) < 0) goto err; + /* + to account binlog event header size + */ + thd->variables.max_allowed_packet += MAX_LOG_EVENT_HEADER; + pthread_mutex_lock(log_lock); /* @@ -1386,7 +1389,6 @@ bool mysql_show_binlog_events(THD* thd) This code will fail on a mixed relay log (one which has Format_desc then Rotate then Format_desc). */ - ev = Log_event::read_log_event(&log,(pthread_mutex_t*)0,description_event); if (ev) { @@ -1578,39 +1580,54 @@ err: DBUG_RETURN(TRUE); } - +/** + Load data's io cache specific hook to be executed + before a chunk of data is being read into the cache's buffer + The fuction instantianates and writes into the binlog + replication events along LOAD DATA processing. + + @param file pointer to io-cache + @return 0 +*/ int log_loaded_block(IO_CACHE* file) { + DBUG_ENTER("log_loaded_block"); LOAD_FILE_INFO *lf_info; - uint block_len ; - - /* file->request_pos contains position where we started last read */ - char* buffer = (char*) file->request_pos; - if (!(block_len = (char*) file->read_end - (char*) buffer)) - return 0; - lf_info = (LOAD_FILE_INFO*) file->arg; + uint block_len; + /* buffer contains position where we started last read */ + uchar* buffer= (uchar*) my_b_get_buffer_start(file); + uint max_event_size= current_thd->variables.max_allowed_packet; + lf_info= (LOAD_FILE_INFO*) file->arg; if (lf_info->thd->current_stmt_binlog_row_based) - return 0; + DBUG_RETURN(0); if (lf_info->last_pos_in_file != HA_POS_ERROR && - lf_info->last_pos_in_file >= file->pos_in_file) - return 0; - lf_info->last_pos_in_file = file->pos_in_file; - if (lf_info->wrote_create_file) - { - Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer, - block_len, lf_info->log_delayed); - mysql_bin_log.write(&a); - } - else + lf_info->last_pos_in_file >= my_b_get_pos_in_file(file)) + DBUG_RETURN(0); + + for (block_len= my_b_get_bytes_in_buffer(file); block_len > 0; + buffer += min(block_len, max_event_size), + block_len -= min(block_len, max_event_size)) { - Begin_load_query_log_event b(lf_info->thd, lf_info->thd->db, - buffer, block_len, - lf_info->log_delayed); - mysql_bin_log.write(&b); - lf_info->wrote_create_file = 1; - DBUG_SYNC_POINT("debug_lock.created_file_event",10); + lf_info->last_pos_in_file= my_b_get_pos_in_file(file); + if (lf_info->wrote_create_file) + { + Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer, + min(block_len, max_event_size), + lf_info->log_delayed); + mysql_bin_log.write(&a); + } + else + { + Begin_load_query_log_event b(lf_info->thd, lf_info->thd->db, + buffer, + min(block_len, max_event_size), + lf_info->log_delayed); + mysql_bin_log.write(&b); + lf_info->wrote_create_file= 1; + DBUG_SYNC_POINT("debug_lock.created_file_event",10); + } } - return 0; + DBUG_RETURN(0); } /* diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3a286a69e20..326fb39cc17 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1579,14 +1579,14 @@ JOIN::reinit() if (exec_tmp_table1) { exec_tmp_table1->file->extra(HA_EXTRA_RESET_STATE); - exec_tmp_table1->file->delete_all_rows(); + exec_tmp_table1->file->ha_delete_all_rows(); free_io_cache(exec_tmp_table1); filesort_free_buffers(exec_tmp_table1,0); } if (exec_tmp_table2) { exec_tmp_table2->file->extra(HA_EXTRA_RESET_STATE); - exec_tmp_table2->file->delete_all_rows(); + exec_tmp_table2->file->ha_delete_all_rows(); free_io_cache(exec_tmp_table2); filesort_free_buffers(exec_tmp_table2,0); } @@ -5630,7 +5630,8 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables, (keyuse->val->type() == Item::REF_ITEM && ((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF && (*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() == - Item_ref::DIRECT_REF) ) + Item_ref::DIRECT_REF && + keyuse->val->real_item()->type() == Item::FIELD_ITEM)) return new store_key_field(thd, key_part->field, key_buff + maybe_null, @@ -9353,6 +9354,8 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, *((*copy_func)++) = item; // Save for copy_funcs if (modify_item) item->set_result_field(new_field); + if (item->type() == Item::NULL_ITEM) + new_field->is_created_from_null_item= TRUE; return new_field; } @@ -10724,7 +10727,7 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table, if (open_tmp_table(&new_table)) goto err1; if (table->file->indexes_are_disabled()) - new_table.file->disable_indexes(HA_KEY_SWITCH_ALL); + new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL); table->file->ha_index_or_rnd_end(); table->file->ha_rnd_init(1); if (table->no_rows) @@ -10753,13 +10756,13 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table, */ while (!table->file->rnd_next(new_table.record[1])) { - write_err= new_table.file->write_row(new_table.record[1]); + write_err= new_table.file->ha_write_row(new_table.record[1]); DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;); if (write_err) goto err; } /* copy row that filled HEAP table */ - if ((write_err=new_table.file->write_row(table->record[0]))) + if ((write_err=new_table.file->ha_write_row(table->record[0]))) { if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) || !ignore_last_dupp_key_error) @@ -10790,7 +10793,7 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table, (void) table->file->ha_rnd_end(); (void) new_table.file->close(); err1: - new_table.file->delete_table(new_table.s->table_name.str); + new_table.file->ha_delete_table(new_table.s->table_name.str); err2: delete new_table.file; thd_proc_info(thd, save_proc_info); @@ -10813,9 +10816,9 @@ free_tmp_table(THD *thd, TABLE *entry) if (entry->file) { if (entry->db_stat) - entry->file->drop_table(entry->s->table_name.str); + entry->file->ha_drop_table(entry->s->table_name.str); else - entry->file->delete_table(entry->s->table_name.str); + entry->file->ha_delete_table(entry->s->table_name.str); delete entry->file; } @@ -12269,7 +12272,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { int error; join->found_records++; - if ((error=table->file->write_row(table->record[0]))) + if ((error=table->file->ha_write_row(table->record[0]))) { if (!table->file->is_fatal_error(error, HA_CHECK_DUP)) goto end; @@ -12331,8 +12334,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { /* Update old record */ restore_record(table,record[1]); update_tmptable_sum_func(join->sum_funcs,table); - if ((error=table->file->update_row(table->record[1], - table->record[0]))) + if ((error=table->file->ha_update_row(table->record[1], + table->record[0]))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ @@ -12355,7 +12358,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), } init_tmptable_sum_functions(join->sum_funcs); copy_funcs(join->tmp_table_param.items_to_copy); - if ((error=table->file->write_row(table->record[0]))) + if ((error=table->file->ha_write_row(table->record[0]))) { if (create_internal_tmp_table_from_heap(join->thd, table, &join->tmp_table_param, error, 0)) @@ -12391,7 +12394,7 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), copy_fields(&join->tmp_table_param); // Groups are copied twice. copy_funcs(join->tmp_table_param.items_to_copy); - if (!(error=table->file->write_row(table->record[0]))) + if (!(error=table->file->ha_write_row(table->record[0]))) join->send_records++; // New group else { @@ -12407,8 +12410,8 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), } restore_record(table,record[1]); update_tmptable_sum_func(join->sum_funcs,table); - if ((error=table->file->update_row(table->record[1], - table->record[0]))) + if ((error=table->file->ha_update_row(table->record[1], + table->record[0]))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ @@ -12451,7 +12454,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), join->sum_funcs_end[send_group_parts]); if (!join->having || join->having->val_int()) { - int error= table->file->write_row(table->record[0]); + int error= table->file->ha_write_row(table->record[0]); if (error && create_internal_tmp_table_from_heap(join->thd, table, &join->tmp_table_param, error, 0)) @@ -13366,7 +13369,8 @@ check_reverse_order: select->quick=tmp; } } - else if (tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts) + else if (tab->type != JT_NEXT && + tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts) { /* SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC @@ -13679,7 +13683,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, } if (having && !having->val_int()) { - if ((error=file->delete_row(record))) + if ((error=file->ha_delete_row(record))) goto err; error=file->rnd_next(record); continue; @@ -13706,7 +13710,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, } if (compare_record(table, first_field) == 0) { - if ((error=file->delete_row(record))) + if ((error=file->ha_delete_row(record))) goto err; } else if (!found) @@ -13806,7 +13810,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, } if (having && !having->val_int()) { - if ((error=file->delete_row(record))) + if ((error=file->ha_delete_row(record))) goto err; continue; } @@ -13823,7 +13827,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, if (hash_search(&hash, org_key_pos, key_length)) { /* Duplicated found ; Remove the row */ - if ((error=file->delete_row(record))) + if ((error=file->ha_delete_row(record))) goto err; } else @@ -15847,7 +15851,7 @@ int JOIN::rollup_write_data(uint idx, TABLE *table_arg) item->save_in_result_field(1); } copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]); - if ((write_error= table_arg->file->write_row(table_arg->record[0]))) + if ((write_error= table_arg->file->ha_write_row(table_arg->record[0]))) { if (create_internal_tmp_table_from_heap(thd, table_arg, &tmp_table_param, write_error, 0)) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 8ba99e57ff1..4643aff95c4 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -5891,7 +5891,7 @@ bool get_schema_tables_result(JOIN *join, { table_list->table->file->extra(HA_EXTRA_NO_CACHE); table_list->table->file->extra(HA_EXTRA_RESET_STATE); - table_list->table->file->delete_all_rows(); + table_list->table->file->ha_delete_all_rows(); free_io_cache(table_list->table); filesort_free_buffers(table_list->table,1); table_list->table->null_row= 0; diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 2e076af45eb..7fa3786c382 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -297,8 +297,8 @@ bool String::copy_aligned(const char *str,uint32 arg_length, uint32 offset, return TRUE; /* - Note, this is only safe for little-endian UCS-2. - If we add big-endian UCS-2 sometimes, this code + Note, this is only safe for big-endian UCS-2. + If we add little-endian UCS-2 sometimes, this code will be more complicated. But it's OK for now. */ bzero((char*) Ptr, offset); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c4897efd447..2438d8fc2ea 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -630,7 +630,7 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) } else { - if ((error= file->delete_table(ddl_log_entry->name))) + if ((error= file->ha_delete_table(ddl_log_entry->name))) { if (error != ENOENT && error != HA_ERR_NO_SUCH_TABLE) break; @@ -667,8 +667,8 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) } else { - if (file->rename_table(ddl_log_entry->from_name, - ddl_log_entry->name)) + if (file->ha_rename_table(ddl_log_entry->from_name, + ddl_log_entry->name)) break; } if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos))) @@ -1299,9 +1299,9 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) lpt->table_name, lpt->create_info, lpt->alter_info->create_list, lpt->key_count, lpt->key_info_buffer, lpt->table->file)) || - lpt->table->file->create_handler_files(shadow_path, NULL, - CHF_CREATE_FLAG, - lpt->create_info)) + lpt->table->file->ha_create_handler_files(shadow_path, NULL, + CHF_CREATE_FLAG, + lpt->create_info)) { my_delete(shadow_frm_name, MYF(0)); error= 1; @@ -1353,15 +1353,15 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) VOID(pthread_mutex_lock(&LOCK_open)); if (my_delete(frm_name, MYF(MY_WME)) || #ifdef WITH_PARTITION_STORAGE_ENGINE - lpt->table->file->create_handler_files(path, shadow_path, - CHF_DELETE_FLAG, NULL) || + lpt->table->file->ha_create_handler_files(path, shadow_path, + CHF_DELETE_FLAG, NULL) || deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos) || (sync_ddl_log(), FALSE) || #endif #ifdef WITH_PARTITION_STORAGE_ENGINE my_rename(shadow_frm_name, frm_name, MYF(MY_WME)) || - lpt->table->file->create_handler_files(path, shadow_path, - CHF_RENAME_FLAG, NULL)) + lpt->table->file->ha_create_handler_files(path, shadow_path, + CHF_RENAME_FLAG, NULL)) #else my_rename(shadow_frm_name, frm_name, MYF(MY_WME))) #endif @@ -3719,14 +3719,14 @@ mysql_rename_table(handlerton *base, const char *old_db, to_base= lc_to; } - if (!file || !(error=file->rename_table(from_base, to_base))) + if (!file || !(error=file->ha_rename_table(from_base, to_base))) { if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext)) { error=my_errno; /* Restore old file name */ if (file) - file->rename_table(to_base, from_base); + file->ha_rename_table(to_base, from_base); } } delete file; @@ -4379,7 +4379,7 @@ send_result_message: if (!result_code) // recreation went ok { if ((table->table= open_ltable(thd, table, lock_type, 0)) && - ((result_code= table->table->file->analyze(thd, check_opt)) > 0)) + ((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0)) result_code= 0; // analyze went ok } if (result_code) // either mysql_recreate_table or analyze failed @@ -4489,7 +4489,7 @@ bool mysql_backup_table(THD* thd, TABLE_LIST* table_list) "MySQL Administrator (mysqldump, mysql)"); DBUG_RETURN(mysql_admin_table(thd, table_list, 0, "backup", TL_READ, 0, 0, 0, 0, - &handler::backup, 0)); + &handler::ha_backup, 0)); } @@ -4501,7 +4501,7 @@ bool mysql_restore_table(THD* thd, TABLE_LIST* table_list) DBUG_RETURN(mysql_admin_table(thd, table_list, 0, "restore", TL_WRITE, 1, 1, 0, &prepare_for_restore, - &handler::restore, 0)); + &handler::ha_restore, 0)); } @@ -4522,7 +4522,7 @@ bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) DBUG_ENTER("mysql_optimize_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, "optimize", TL_WRITE, 1,0,0,0, - &handler::optimize, 0)); + &handler::ha_optimize, 0)); } @@ -4936,7 +4936,7 @@ bool mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) DBUG_ENTER("mysql_analyze_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, "analyze", lock_type, 1, 0, 0, 0, - &handler::analyze, 0)); + &handler::ha_analyze, 0)); } @@ -4983,7 +4983,7 @@ mysql_discard_or_import_tablespace(THD *thd, DBUG_RETURN(-1); } - error=table->file->discard_or_import_tablespace(discard); + error= table->file->ha_discard_or_import_tablespace(discard); thd_proc_info(thd, "end"); @@ -5355,14 +5355,14 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled, switch (keys_onoff) { case ENABLE: - error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); + error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); break; case LEAVE_AS_IS: if (!indexes_were_disabled) break; /* fall-through: disabled indexes */ case DISABLE: - error= table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); + error= table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); } if (error == HA_ERR_WRONG_COMMAND) @@ -6132,14 +6132,14 @@ view_err: wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); VOID(pthread_mutex_unlock(&LOCK_open)); DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000);); - error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); + error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); /* COND_refresh will be signaled in close_thread_tables() */ break; case DISABLE: VOID(pthread_mutex_lock(&LOCK_open)); wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); VOID(pthread_mutex_unlock(&LOCK_open)); - error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); + error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); /* COND_refresh will be signaled in close_thread_tables() */ break; default: @@ -6547,7 +6547,7 @@ view_err: KEY_PART_INFO *part_end; DBUG_PRINT("info", ("No new_table, checking add/drop index")); - table->file->prepare_for_alter(); + table->file->ha_prepare_for_alter(); if (index_add_count) { /* The add_index() method takes an array of KEY structs. */ @@ -6765,8 +6765,8 @@ view_err: t_table= table; } /* Tell the handler that a new frm file is in place. */ - if (t_table->file->create_handler_files(path, NULL, CHF_INDEX_FLAG, - create_info)) + if (t_table->file->ha_create_handler_files(path, NULL, CHF_INDEX_FLAG, + create_info)) goto err_with_placeholders; if (thd->locked_tables && new_name == table_name && new_db == db) { @@ -7064,7 +7064,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, copy_ptr->do_copy(copy_ptr); } prev_insert_id= to->file->next_insert_id; - error=to->file->write_row(to->record[0]); + error=to->file->ha_write_row(to->record[0]); to->auto_increment_field_not_null= FALSE; if (error) { diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 90d7b4dfc60..cee1c9d6bd4 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -440,10 +440,10 @@ bool st_select_lex_unit::exec() { item->assigned(0); // We will reinit & rexecute unit item->reset(); - table->file->delete_all_rows(); + table->file->ha_delete_all_rows(); } /* re-enabling indexes for next subselect iteration */ - if (union_distinct && table->file->enable_indexes(HA_KEY_SWITCH_ALL)) + if (union_distinct && table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL)) { DBUG_ASSERT(0); } @@ -485,7 +485,7 @@ bool st_select_lex_unit::exec() sl->join->exec(); if (sl == union_distinct) { - if (table->file->disable_indexes(HA_KEY_SWITCH_ALL)) + if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL)) DBUG_RETURN(TRUE); table->no_keyread=1; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 6d0d5933971..eb44a13826c 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -526,7 +526,9 @@ int mysql_update(THD *thd, init_read_record(&info,thd,table,select,0,1); updated= found= 0; - thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */ + /* Generate an error when trying to set a NOT NULL field to NULL. */ + thd->count_cuted_fields= ignore ? CHECK_FIELD_WARN + : CHECK_FIELD_ERROR_FOR_NULL; thd->cuted_fields=0L; thd_proc_info(thd, "Updating"); @@ -623,9 +625,9 @@ int mysql_update(THD *thd, call then it should be included in the count of dup_key_found and error should be set to 0 (only if these errors are ignored). */ - error= table->file->bulk_update_row(table->record[1], - table->record[0], - &dup_key_found); + error= table->file->ha_bulk_update_row(table->record[1], + table->record[0], + &dup_key_found); limit+= dup_key_found; updated-= dup_key_found; } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 79973b85181..da301b37484 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1465,6 +1465,8 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) char *wrong_object_db= NULL, *wrong_object_name= NULL; bool error= FALSE; enum legacy_db_type not_used; + bool some_views_deleted= FALSE; + bool something_wrong= FALSE; DBUG_ENTER("mysql_drop_view"); VOID(pthread_mutex_lock(&LOCK_open)); @@ -1506,6 +1508,8 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) if (my_delete(path, MYF(MY_WME))) error= TRUE; + some_views_deleted= TRUE; + /* For a view, there is only one table_share object which should never be used outside of LOCK_open @@ -1523,29 +1527,32 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) sp_cache_invalidate(); } - if (error) - { - VOID(pthread_mutex_unlock(&LOCK_open)); - DBUG_RETURN(TRUE); - } if (wrong_object_name) { - VOID(pthread_mutex_unlock(&LOCK_open)); my_error(ER_WRONG_OBJECT, MYF(0), wrong_object_db, wrong_object_name, "VIEW"); - DBUG_RETURN(TRUE); } if (non_existant_views.length()) { - VOID(pthread_mutex_unlock(&LOCK_open)); my_error(ER_BAD_TABLE_ERROR, MYF(0), non_existant_views.c_ptr()); - DBUG_RETURN(TRUE); } - write_bin_log(thd, TRUE, thd->query, thd->query_length); + something_wrong= error || wrong_object_name || non_existant_views.length(); + if (some_views_deleted || !something_wrong) + { + /* if something goes wrong, bin-log with possible error code, + otherwise bin-log with error code cleared. + */ + write_bin_log(thd, !something_wrong, thd->query, thd->query_length); + } - send_ok(thd); VOID(pthread_mutex_unlock(&LOCK_open)); + + if (something_wrong) + { + DBUG_RETURN(TRUE); + } + send_ok(thd); DBUG_RETURN(FALSE); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 42fc5b6cbe1..c00394d96cf 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -509,10 +509,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %pure_parser /* We have threads */ /* - Currently there are 177 shift/reduce conflicts. + Currently there are 169 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 177 +%expect 169 /* Comments for TOKENS. @@ -1209,7 +1209,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <table_list> join_table_list join_table - table_factor table_ref + table_factor table_ref esc_table_ref select_derived derived_table_list %type <date_time_type> date_time_type; @@ -1300,7 +1300,9 @@ END_OF_INPUT %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt %type <NONE> sp_proc_stmt_statement sp_proc_stmt_return %type <NONE> sp_proc_stmt_if -%type <NONE> sp_labeled_control sp_proc_stmt_unlabeled sp_proc_stmt_leave +%type <NONE> sp_labeled_control sp_proc_stmt_unlabeled +%type <NONE> sp_labeled_block sp_unlabeled_block +%type <NONE> sp_proc_stmt_leave %type <NONE> sp_proc_stmt_iterate %type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close %type <NONE> case_stmt_specification simple_case_stmt searched_case_stmt @@ -1961,6 +1963,8 @@ ev_sql_stmt_inner: | sp_proc_stmt_return | sp_proc_stmt_if | case_stmt_specification + | sp_labeled_block + | sp_unlabeled_block | sp_labeled_control | sp_proc_stmt_unlabeled | sp_proc_stmt_leave @@ -2535,6 +2539,8 @@ sp_proc_stmt: | sp_proc_stmt_return | sp_proc_stmt_if | case_stmt_specification + | sp_labeled_block + | sp_unlabeled_block | sp_labeled_control | sp_proc_stmt_unlabeled | sp_proc_stmt_leave @@ -2661,14 +2667,35 @@ sp_proc_stmt_leave: sp_instr_jump *i; uint ip= sp->instructions(); uint n; + /* + When jumping to a BEGIN-END block end, the target jump + points to the block hpop/cpop cleanup instructions, + so we should exclude the block context here. + When jumping to something else (i.e., SP_LAB_ITER), + there are no hpop/cpop at the jump destination, + so we should include the block context here for cleanup. + */ + bool exclusive= (lab->type == SP_LAB_BEGIN); - n= ctx->diff_handlers(lab->ctx, TRUE); /* Exclusive the dest. */ + n= ctx->diff_handlers(lab->ctx, exclusive); if (n) - sp->add_instr(new sp_instr_hpop(ip++, ctx, n)); - n= ctx->diff_cursors(lab->ctx, TRUE); /* Exclusive the dest. */ + { + sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n); + if (hpop == NULL) + MYSQL_YYABORT; + sp->add_instr(hpop); + } + n= ctx->diff_cursors(lab->ctx, exclusive); if (n) - sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); + { + sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n); + if (cpop == NULL) + MYSQL_YYABORT; + sp->add_instr(cpop); + } i= new sp_instr_jump(ip, ctx); + if (i == NULL) + MYSQL_YYABORT; sp->push_backpatch(i, lab); /* Jumping forward */ sp->add_instr(i); } @@ -2696,10 +2723,20 @@ sp_proc_stmt_iterate: n= ctx->diff_handlers(lab->ctx, FALSE); /* Inclusive the dest. */ if (n) - sp->add_instr(new sp_instr_hpop(ip++, ctx, n)); + { + sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n); + if (hpop == NULL) + MYSQL_YYABORT; + sp->add_instr(hpop); + } n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */ if (n) - sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); + { + sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n); + if (cpop == NULL) + MYSQL_YYABORT; + sp->add_instr(cpop); + } i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */ sp->add_instr(i); } @@ -2983,19 +3020,17 @@ sp_labeled_control: sp_unlabeled_control sp_opt_label { LEX *lex= Lex; + sp_label_t *lab= lex->spcont->pop_label(); if ($5.str) { - sp_label_t *lab= lex->spcont->find_label($5.str); - - if (!lab || - my_strcasecmp(system_charset_info, $5.str, lab->name) != 0) + if (my_strcasecmp(system_charset_info, $5.str, lab->name) != 0) { my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str); MYSQL_YYABORT; } } - lex->sphead->backpatch(lex->spcont->pop_label()); + lex->sphead->backpatch(lab); } ; @@ -3004,15 +3039,59 @@ sp_opt_label: | label_ident { $$= $1; } ; -sp_unlabeled_control: +sp_labeled_block: + label_ident ':' + { + LEX *lex= Lex; + sp_pcontext *ctx= lex->spcont; + sp_label_t *lab= ctx->find_label($1.str); + + if (lab) + { + my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str); + MYSQL_YYABORT; + } + + lab= lex->spcont->push_label($1.str, + lex->sphead->instructions()); + lab->type= SP_LAB_BEGIN; + } + sp_block_content sp_opt_label + { + LEX *lex= Lex; + sp_label_t *lab= lex->spcont->pop_label(); + + if ($5.str) + { + if (my_strcasecmp(system_charset_info, $5.str, lab->name) != 0) + { + my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str); + MYSQL_YYABORT; + } + } + } + ; + +sp_unlabeled_block: + { /* Unlabeled blocks get a secret label. */ + LEX *lex= Lex; + uint ip= lex->sphead->instructions(); + sp_label_t *lab= lex->spcont->push_label((char *)"", ip); + lab->type= SP_LAB_BEGIN; + } + sp_block_content + { + LEX *lex= Lex; + lex->spcont->pop_label(); + } + ; + +sp_block_content: BEGIN_SYM { /* QQ This is just a dummy for grouping declarations and statements together. No [[NOT] ATOMIC] yet, and we need to figure out how make it coexist with the existing BEGIN COMMIT/ROLLBACK. */ LEX *lex= Lex; - sp_label_t *lab= lex->spcont->last_label(); - - lab->type= SP_LAB_BEGIN; lex->spcont= lex->spcont->push_context(LABEL_DEFAULT_SCOPE); } sp_decls @@ -3032,7 +3111,10 @@ sp_unlabeled_control: $3.curs)); lex->spcont= ctx->pop_context(); } - | LOOP_SYM + ; + +sp_unlabeled_control: + LOOP_SYM sp_proc_stmts1 END LOOP_SYM { LEX *lex= Lex; @@ -6176,6 +6258,14 @@ select_paren: my_parse_error(ER(ER_SYNTAX_ERROR)); MYSQL_YYABORT; } + if (sel->linkage == UNION_TYPE && + sel->olap != UNSPECIFIED_OLAP_TYPE && + sel->master_unit()->fake_select_lex) + { + my_error(ER_WRONG_USAGE, MYF(0), + "CUBE/ROLLUP", "ORDER BY"); + MYSQL_YYABORT; + } /* select in braces, can't contain global parameters */ if (sel->master_unit()->fake_select_lex) sel->master_unit()->global_parameters= @@ -7469,10 +7559,22 @@ join_table_list: derived_table_list { MYSQL_YYABORT_UNLESS($$=$1); } ; +/* + The ODBC escape syntax for Outer Join is: '{' OJ join_table '}' + The parser does not define OJ as a token, any ident is accepted + instead in $2 (ident). Also, all productions from table_ref can + be escaped, not only join_table. Both syntax extensions are safe + and are ignored. +*/ +esc_table_ref: + table_ref { $$=$1; } + | '{' ident table_ref '}' { $$=$3; } + ; + /* Warning - may return NULL in case of incomplete SELECT */ derived_table_list: - table_ref { $$=$1; } - | derived_table_list ',' table_ref + esc_table_ref { $$=$1; } + | derived_table_list ',' esc_table_ref { MYSQL_YYABORT_UNLESS($1 && ($$=$3)); } @@ -7637,25 +7739,6 @@ table_factor: MYSQL_YYABORT; Select->add_joined_table($$); } - | '{' ident table_ref LEFT OUTER JOIN_SYM table_ref - ON - { - /* Change the current name resolution context to a local context. */ - if (push_new_name_resolution_context(YYTHD, $3, $7)) - MYSQL_YYABORT; - - } - expr '}' - { - LEX *lex= Lex; - MYSQL_YYABORT_UNLESS($3 && $7); - add_join_on($7,$10); - Lex->pop_context(); - $7->outer_join|=JOIN_TYPE_LEFT; - $$=$7; - if (!($$= lex->current_select->nest_last_join(lex->thd))) - MYSQL_YYABORT; - } | select_derived_init get_select_lex select_derived2 { LEX *lex= Lex; @@ -8064,7 +8147,8 @@ order_clause: SELECT_LEX *sel= lex->current_select; SELECT_LEX_UNIT *unit= sel-> master_unit(); if (sel->linkage != GLOBAL_OPTIONS_TYPE && - sel->olap != UNSPECIFIED_OLAP_TYPE) + sel->olap != UNSPECIFIED_OLAP_TYPE && + (sel->linkage != UNION_TYPE || sel->braces)) { my_error(ER_WRONG_USAGE, MYF(0), "CUBE/ROLLUP", "ORDER BY"); diff --git a/sql/unireg.cc b/sql/unireg.cc index e5f230841f6..64a5b7d8910 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -227,6 +227,14 @@ bool mysql_create_frm(THD *thd, const char *file_name, strmake((char*) forminfo+47, create_info->comment.str ? create_info->comment.str : "", create_info->comment.length); forminfo[46]=(uchar) create_info->comment.length; +#ifdef EXTRA_DEBUG + /* + EXTRA_DEBUG causes strmake() to initialize its buffer behind the + payload with a magic value to detect wrong buffer-sizes. We + explicitly zero that segment again. + */ + memset((char*) forminfo+47 + forminfo[46], 0, 61 - forminfo[46]); +#endif #ifdef WITH_PARTITION_STORAGE_ENGINE if (part_info) { @@ -395,7 +403,7 @@ int rea_create_table(THD *thd, const char *path, DBUG_ASSERT(*fn_rext(frm_name)); if (thd->variables.keep_files_on_create) create_info->options|= HA_CREATE_KEEP_FILES; - if (file->create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info)) + if (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info)) goto err_handler; if (!create_info->frm_only && ha_create_table(thd, path, db, table_name, create_info,0)) @@ -403,7 +411,7 @@ int rea_create_table(THD *thd, const char *path, DBUG_RETURN(0); err_handler: - VOID(file->create_handler_files(path, NULL, CHF_DELETE_FLAG, create_info)); + VOID(file->ha_create_handler_files(path, NULL, CHF_DELETE_FLAG, create_info)); my_delete(frm_name, MYF(0)); DBUG_RETURN(1); } /* rea_create_table */ diff --git a/strings/decimal.c b/strings/decimal.c index f457014b2b1..0559dd97613 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -1601,9 +1601,21 @@ decimal_round(decimal_t *from, decimal_t *to, int scale, x+=10; *buf1=powers10[pos]*(x-y); } - if (frac0 < 0) + /* + In case we're rounding e.g. 1.5e9 to 2.0e9, the decimal_digit_t's inside + the buffer are as follows. + + Before <1, 5e8> + After <2, 5e8> + + Hence we need to set the 2nd field to 0. + The same holds if we round 1.5e-9 to 2e-9. + */ + if (frac0 < frac1) { - dec1 *end=to->buf+intg0, *buf=buf1+1; + dec1 *buf= to->buf + ((scale == 0 && intg0 == 0) ? 1 : intg0 + frac0); + dec1 *end= to->buf + len; + while (buf < end) *buf++=0; } diff --git a/strings/strmake.c b/strings/strmake.c index 0d26e1b61a9..df8d78e8476 100644 --- a/strings/strmake.c +++ b/strings/strmake.c @@ -27,23 +27,25 @@ #include <my_global.h> #include "m_string.h" -#ifdef BAD_STRING_COMPILER - -char *strmake(char *dst,const char *src,uint length) +char *strmake(register char *dst, register const char *src, size_t length) { - reg1 char *res; - - if ((res=memccpy(dst,src,0,length))) - return res-1; - dst[length]=0; - return dst+length; -} - -#define strmake strmake_overlapp /* Use orginal for overlapping str */ +#ifdef EXTRA_DEBUG + /* + 'length' is the maximum length of the string; the buffer needs + to be one character larger to accomodate the terminating '\0'. + This is easy to get wrong, so we make sure we write to the + entire length of the buffer to identify incorrect buffer-sizes. + We only initialise the "unused" part of the buffer here, a) for + efficiency, and b) because dst==src is allowed, so initialising + the entire buffer would overwrite the source-string. Also, we + write a character rather than '\0' as this makes spotting these + problems in the results easier. + */ + uint n= strlen(src) + 1; + if (n <= length) + memset(dst + n, (int) 'Z', length - n + 1); #endif -char *strmake(register char *dst, register const char *src, size_t length) -{ while (length--) if (! (*dst++ = *src++)) return dst-1; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 9284b2182b1..3776be79399 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -15674,7 +15674,7 @@ static void test_mysql_insert_id() myquery(rc); res= mysql_insert_id(mysql); DIE_UNLESS(res == 0); - rc= mysql_query(mysql, "update t2 set f1=NULL where f1=14"); + rc= mysql_query(mysql, "update t2 set f1=0 where f1=14"); myquery(rc); res= mysql_insert_id(mysql); DIE_UNLESS(res == 0); |