summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysql_upgrade.c27
-rw-r--r--client/mysqlcheck.c19
-rw-r--r--libmysqld/libmysqld.c1
-rw-r--r--mysql-test/extra/binlog_tests/drop_temp_table.test57
-rw-r--r--mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test12
-rw-r--r--mysql-test/include/have_mysql_upgrade.inc4
-rw-r--r--mysql-test/include/mtr_warnings.sql1
-rwxr-xr-xmysql-test/mysql-stress-test.pl133
-rw-r--r--mysql-test/r/delete.result45
-rw-r--r--mysql-test/r/join.result10
-rw-r--r--mysql-test/r/subselect4.result31
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result40
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result54
-rw-r--r--mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result8
-rw-r--r--mysql-test/suite/rpl/r/rpl_log_pos.result1
-rw-r--r--mysql-test/suite/rpl/r/rpl_mysql_upgrade.result13
-rw-r--r--mysql-test/suite/rpl/r/rpl_packet.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_disabled_slave_key.result26
-rw-r--r--mysql-test/suite/rpl/t/disabled.def1
-rw-r--r--mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_log_pos.test1
-rw-r--r--mysql-test/suite/rpl/t/rpl_mysql_upgrade.test56
-rw-r--r--mysql-test/suite/rpl/t/rpl_packet.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_disabled_slave_key.test73
-rw-r--r--mysql-test/t/delete.test44
-rw-r--r--mysql-test/t/join.test20
-rw-r--r--mysql-test/t/subselect4.test32
-rw-r--r--mysql-test/valgrind.supp99
-rw-r--r--mysys/my_thr_init.c7
-rw-r--r--sql/debug_sync.cc2
-rw-r--r--sql/item.cc21
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/log_event.cc4
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_delete.cc148
-rw-r--r--sql/sql_select.cc8
-rw-r--r--sql/sql_table.cc2
-rw-r--r--storage/myisam/mi_check.c6
-rw-r--r--support-files/binary-configure.sh24
39 files changed, 886 insertions, 155 deletions
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index cfd7ed4ea56..52c3636219d 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -54,6 +54,8 @@ static char **defaults_argv;
static my_bool not_used; /* Can't use GET_BOOL without a value pointer */
+static my_bool opt_write_binlog;
+
#include <help_start.h>
static struct my_option my_long_options[]=
@@ -124,6 +126,11 @@ static struct my_option my_long_options[]=
{"verbose", 'v', "Display more output about the process",
(uchar**) &opt_verbose, (uchar**) &opt_verbose, 0,
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"write-binlog", OPT_WRITE_BINLOG,
+ "All commands including mysqlcheck are binlogged. Enabled by default;"
+ "use --skip-write-binlog when commands should not be sent to replication slaves.",
+ (uchar**) &opt_write_binlog, (uchar**) &opt_write_binlog, 0, GET_BOOL, NO_ARG,
+ 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -448,6 +455,8 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
int ret;
File fd;
char query_file_path[FN_REFLEN];
+ const uchar sql_log_bin[]= "SET SQL_LOG_BIN=0;";
+
DBUG_ENTER("run_query");
DBUG_PRINT("enter", ("query: %s", query));
if ((fd= create_temp_file(query_file_path, opt_tmpdir,
@@ -455,6 +464,22 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
MYF(MY_WME))) < 0)
die("Failed to create temporary file for defaults");
+ /*
+ Master and slave should be upgraded separately. All statements executed
+ by mysql_upgrade will not be binlogged.
+ 'SET SQL_LOG_BIN=0' is executed before any other statements.
+ */
+ if (!opt_write_binlog)
+ {
+ if (my_write(fd, sql_log_bin, sizeof(sql_log_bin)-1,
+ MYF(MY_FNABP | MY_WME)))
+ {
+ my_close(fd, MYF(0));
+ my_delete(query_file_path, MYF(0));
+ die("Failed to write to '%s'", query_file_path);
+ }
+ }
+
if (my_write(fd, (uchar*) query, strlen(query),
MYF(MY_FNABP | MY_WME)))
{
@@ -648,6 +673,7 @@ static int run_mysqlcheck_upgrade(void)
"--check-upgrade",
"--all-databases",
"--auto-repair",
+ opt_write_binlog ? "--write-binlog" : "--skip-write-binlog",
NULL);
}
@@ -662,6 +688,7 @@ static int run_mysqlcheck_fixnames(void)
"--all-databases",
"--fix-db-names",
"--fix-table-names",
+ opt_write_binlog ? "--write-binlog" : "--skip-write-binlog",
NULL);
}
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 82aabd77b24..1533e602639 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -652,6 +652,17 @@ static int use_db(char *database)
return 0;
} /* use_db */
+static int disable_binlog()
+{
+ const char *stmt= "SET SQL_LOG_BIN=0";
+ if (mysql_query(sock, stmt))
+ {
+ fprintf(stderr, "Failed to %s\n", stmt);
+ fprintf(stderr, "Error: %s\n", mysql_error(sock));
+ return 1;
+ }
+ return 0;
+}
static int handle_request_for_tables(char *tables, uint length)
{
@@ -844,6 +855,14 @@ int main(int argc, char **argv)
if (dbConnect(current_host, current_user, opt_password))
exit(EX_MYSQLERR);
+ if (!opt_write_binlog)
+ {
+ if (disable_binlog()) {
+ first_error= 1;
+ goto end;
+ }
+ }
+
if (opt_auto_repair &&
my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64))
{
diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c
index aff9391e015..0c20b35236d 100644
--- a/libmysqld/libmysqld.c
+++ b/libmysqld/libmysqld.c
@@ -164,6 +164,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
port=0;
unix_socket=0;
+ client_flag|=mysql->options.client_flag;
/* Send client information for access check */
client_flag|=CLIENT_CAPABILITIES;
if (client_flag & CLIENT_MULTI_STATEMENTS)
diff --git a/mysql-test/extra/binlog_tests/drop_temp_table.test b/mysql-test/extra/binlog_tests/drop_temp_table.test
index 7d37fca2bef..5616fb4a643 100644
--- a/mysql-test/extra/binlog_tests/drop_temp_table.test
+++ b/mysql-test/extra/binlog_tests/drop_temp_table.test
@@ -1,27 +1,62 @@
--disable_warnings
-drop database if exists `drop-temp+table-test`;
+DROP DATABASE IF EXISTS `drop-temp+table-test`;
--enable_warnings
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
connection con1;
-reset master;
-create database `drop-temp+table-test`;
-use `drop-temp+table-test`;
-create temporary table shortn1 (a int);
-create temporary table `table:name` (a int);
-create temporary table shortn2 (a int);
-select get_lock("a",10);
+RESET MASTER;
+CREATE DATABASE `drop-temp+table-test`;
+USE `drop-temp+table-test`;
+CREATE TEMPORARY TABLE shortn1 (a INT);
+CREATE TEMPORARY TABLE `table:name` (a INT);
+CREATE TEMPORARY TABLE shortn2 (a INT);
+
+##############################################################################
+# BUG#46572 DROP TEMPORARY table IF EXISTS does not have a consistent behavior
+# in ROW mode
+#
+# In RBR, 'DROP TEMPORARY TABLE ...' statement should never be binlogged no
+# matter if the tables exist or not. In contrast, both in SBR and MBR, the
+# statement should be always binlogged no matter if the tables exist or not.
+##############################################################################
+CREATE TEMPORARY TABLE tmp(c1 int);
+CREATE TEMPORARY TABLE tmp1(c1 int);
+CREATE TEMPORARY TABLE tmp2(c1 int);
+CREATE TEMPORARY TABLE tmp3(c1 int);
+CREATE TABLE t(c1 int);
+
+DROP TEMPORARY TABLE IF EXISTS tmp;
+
+--disable_warnings
+# Before fixing BUG#46572, 'DROP TEMPORARY TABLE IF EXISTS...' statement was
+# binlogged when the table did not exist in RBR.
+DROP TEMPORARY TABLE IF EXISTS tmp;
+
+# In RBR, 'DROP TEMPORARY TABLE ...' statement is never binlogged no matter if
+# the tables exist or not.
+DROP TEMPORARY TABLE IF EXISTS tmp, tmp1;
+DROP TEMPORARY TABLE tmp3;
+
+#In RBR, tmp2 will NOT be binlogged, because it is a temporary table.
+DROP TABLE IF EXISTS tmp2, t;
+
+#In RBR, tmp2 will be binlogged, because it does not exist and master do not know
+# whether it is a temporary table or not.
+DROP TABLE IF EXISTS tmp2, t;
+--enable_warnings
+
+SELECT GET_LOCK("a",10);
disconnect con1;
connection con2;
# We want to SHOW BINLOG EVENTS, to know what was logged. But there is no
# guarantee that logging of the terminated con1 has been done yet.
# To be sure that logging has been done, we use a user lock.
-select get_lock("a",10);
-let $VERSION=`select version()`;
+SELECT GET_LOCK("a",10);
+let $VERSION=`SELECT VERSION()`;
source include/show_binlog_events.inc;
-drop database `drop-temp+table-test`;
+DROP DATABASE `drop-temp+table-test`;
# End of 4.1 tests
diff --git a/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test b/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test
index c79ccdd044f..89c136d8893 100644
--- a/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test
+++ b/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test
@@ -41,7 +41,17 @@ eval SELECT RELEASE_LOCK($debug_lock);
connection slave;
source include/wait_for_slave_io_error.inc;
let $last_io_errno= query_get_value("show slave status", Last_IO_Errno, 1);
-echo Slave_IO_Errno= $last_io_errno;
+--echo Check network error happened here
+if (`SELECT '$last_io_errno' = '2013' || # CR_SERVER_LOST
+ '$last_io_errno' = '2003' || # CR_CONN_HOST_ERROR
+ '$last_io_errno' = '2002' || # CR_CONNECTION_ERROR
+ '$last_io_errno' = '2006' || # CR_SERVER_GONE_ERROR
+ '$last_io_errno' = '1040' || # ER_CON_COUNT_ERROR
+ '$last_io_errno' = '1053' # ER_SERVER_SHUTDOWN
+ `)
+{
+ --echo NETWORK ERROR
+}
# Write file to make mysql-test-run.pl start up the server again
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
diff --git a/mysql-test/include/have_mysql_upgrade.inc b/mysql-test/include/have_mysql_upgrade.inc
new file mode 100644
index 00000000000..8f486176018
--- /dev/null
+++ b/mysql-test/include/have_mysql_upgrade.inc
@@ -0,0 +1,4 @@
+--require r/have_mysql_upgrade.result
+--disable_query_log
+select LENGTH("$MYSQL_UPGRADE")>0 as have_mysql_upgrade;
+--enable_query_log
diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql
index 2156c37f3e3..134e448953a 100644
--- a/mysql-test/include/mtr_warnings.sql
+++ b/mysql-test/include/mtr_warnings.sql
@@ -173,6 +173,7 @@ INSERT INTO global_suppressions VALUES
this error message.
*/
("Can't find file: '.\\\\test\\\\\\?{8}.frm'"),
+ ("Slave: Unknown table 't1' Error_code: 1051"),
("THE_LAST_SUPPRESSION")||
diff --git a/mysql-test/mysql-stress-test.pl b/mysql-test/mysql-stress-test.pl
index 3061506da51..c80706d9f25 100755
--- a/mysql-test/mysql-stress-test.pl
+++ b/mysql-test/mysql-stress-test.pl
@@ -14,17 +14,16 @@
#
# Design of stress script should allow one:
#
-# - To stress test the mysqltest binary test engine.
-# - To stress test the regular test suite and any additional test suites
-# (such as mysql-test-extra-5.0).
-# - To specify files with lists of tests both for initialization of
-# stress db and for further testing itself.
-# - To define the number of threads to be concurrently used in testing.
-# - To define limitations for the test run. such as the number of tests or
-# loops for execution or duration of testing, delay between test
-# executions, and so forth.
-# - To get a readable log file that can be used for identification of
-# errors that occur during testing.
+# - to use for stress testing mysqltest binary as test engine
+# - to use for stress testing both regular test suite and any
+# additional test suites (e.g. mysql-test-extra-5.0)
+# - to specify files with lists of tests both for initialization of
+# stress db and for further testing itself
+# - to define number of threads that will be concurrently used in testing
+# - to define limitations for test run. e.g. number of tests or loops
+# for execution or duration of testing, delay between test executions, etc.
+# - to get readable log file which can be used for identification of
+# errors arose during testing
#
# Basic scenarios:
#
@@ -58,6 +57,8 @@
# to reproduce and debug errors that was found in continued stress
# testing
#
+# 2009-01-28 OBN Additions and modifications per WL#4685
+#
########################################################################
use Config;
@@ -114,13 +115,15 @@ $opt_stress_mode="random";
$opt_loop_count=0;
$opt_test_count=0;
$opt_test_duration=0;
-$opt_abort_on_error=0;
+# OBN: Changing abort-on-error default to -1 (for WL-4626/4685): -1 means no abort
+$opt_abort_on_error=-1;
$opt_sleep_time = 0;
$opt_threads=1;
$pid_file="mysql_stress_test.pid";
$opt_mysqltest= ($^O =~ /mswin32/i) ? "mysqltest.exe" : "mysqltest";
$opt_check_tests_file="";
-@mysqltest_args=("--silent", "-v", "--skip-safemalloc");
+# OBM adding a setting for 'max-connect-retries=7' the default of 500 is to high
+@mysqltest_args=("--silent", "-v", "--skip-safemalloc", "--max-connect-retries=7");
# Client ip address
$client_ip=inet_ntoa((gethostbyname(hostname()))[4]);
@@ -133,24 +136,31 @@ $client_ip=~ s/\.//g;
#
# S1 - Critical errors - cause immediately abort of testing. These errors
# could be caused by server crash or impossibility
-# of test execution
+# of test execution.
#
# S2 - Serious errors - these errors are bugs for sure as it knowns that
# they shouldn't appear during stress testing
#
-# S3 - Non-seriuos errros - these errors could be caused by fact that
+# S3 - Unknown errors - Errors were returned but we don't know what they are
+# so script can't determine if they are OK or not
+#
+# S4 - Non-seriuos errros - these errors could be caused by fact that
# we execute simultaneously statements that
# affect tests executed by other threads
%error_strings = ( 'Failed in mysql_real_connect()' => S1,
+ 'Can\'t connect' => S1,
'not found (Errcode: 2)' => S1 );
%error_codes = ( 1012 => S2, 1015 => S2, 1021 => S2,
1027 => S2, 1037 => S2, 1038 => S2,
1039 => S2, 1040 => S2, 1046 => S2,
- 1180 => S2, 1181 => S2, 1203 => S2,
- 1205 => S2, 1206 => S2, 1207 => S2,
- 1223 => S2, 2013 => S1);
+ 1053 => S2, 1180 => S2, 1181 => S2,
+ 1203 => S2, 1205 => S4, 1206 => S2,
+ 1207 => S2, 1213 => S4, 1223 => S2,
+ 2002 => S1, 2003 => S1, 2006 => S1,
+ 2013 => S1
+ );
share(%test_counters);
%test_counters=( loop_count => 0, test_count=>0);
@@ -158,6 +168,35 @@ share(%test_counters);
share($exiting);
$exiting=0;
+# OBN Code and 'set_exit_code' function added by ES to set an exit code based on the error category returned
+# in combination with the --abort-on-error value see WL#4685)
+use constant ABORT_MAKEWEIGHT => 20;
+share($gExitCode);
+$gExitCode = 0; # global exit code
+sub set_exit_code {
+ my $severity = shift;
+ my $code = 0;
+ if ( $severity =~ /^S(\d+)/ ) {
+ $severity = $1;
+ $code = 11 - $severity; # S1=10, S2=9, ... -- as per WL
+ }
+ else {
+ # we know how we call the sub: severity should be S<num>; so, we should never be here...
+ print STDERR "Unknown severity format: $severity; setting to S1\n";
+ $severity = 1;
+ }
+ $abort = 0;
+ if ( $severity <= $opt_abort_on_error ) {
+ # the test finished with a failure severe enough to abort. We are adding the 'abort flag' to the exit code
+ $code += ABORT_MAKEWEIGHT;
+ # but are not exiting just yet -- we need to update global exit code first
+ $abort = 1;
+ }
+ lock $gExitCode; # we can use lock here because the script uses threads anyway
+ $gExitCode = $code if $code > $gExitCode;
+ kill INT, $$ if $abort; # this is just a way to call sig_INT_handler: it will set exiting flag, which should do the rest
+}
+
share($test_counters_lock);
$test_counters_lock=0;
share($log_file_lock);
@@ -176,7 +215,8 @@ GetOptions("server-host=s", "server-logs-dir=s", "server-port=s",
"threads=s", "sleep-time=s", "loop-count=i", "test-count=i",
"test-duration=i", "test-suffix=s", "check-tests-file",
"verbose", "log-error-details", "cleanup", "mysqltest=s",
- "abort-on-error", "help") || usage();
+ # OBN: (changing 'abort-on-error' to numberic for WL-4626/4685)
+ "abort-on-error=i" => \$opt_abort_on_error, "help") || usage();
usage() if ($opt_help);
@@ -563,7 +603,15 @@ EOF
if ($opt_test_duration)
{
- sleep($opt_test_duration);
+ # OBN - At this point we need to wait for the duration of the test, hoever
+ # we need to be able to quit if an 'abort-on-error' condition has happend
+ # with one of the children (WL#4685). Using solution by ES and replacing
+ # the 'sleep' command with a loop checking the abort condition every second
+
+ foreach ( 1..$opt_test_duration ) {
+ last if $exiting;
+ sleep 1;
+ }
kill INT, $$; #Interrupt child threads
}
@@ -580,6 +628,8 @@ EOF
print "EXIT\n";
}
+exit $gExitCode; # ES WL#4685: script should return a meaningful exit code
+
sub test_init
{
my ($env)=@_;
@@ -681,7 +731,9 @@ sub test_execute
{
if (!exists($error_codes{$err_code}))
{
- $severity="S3";
+ # OBN Changing severity level to S4 from S3 as S3 now reserved
+ # for the case where the error is unknown (for WL#4626/4685
+ $severity="S4";
$err_code=0;
}
else
@@ -734,6 +786,7 @@ sub test_execute
{
push @{$env->{test_status}}, "Severity $severity: $total";
$env->{errors}->{total}=+$total;
+ set_exit_code($severity);
}
}
@@ -748,18 +801,20 @@ sub test_execute
log_session_errors($env, $test_file);
- if (!$exiting && ($signal_num == 2 || $signal_num == 15 ||
- ($opt_abort_on_error && $env->{errors}->{S1} > 0)))
+ #OBN Removing the case of S1 and abort-on-error as that is now set
+ # inside the set_exit_code function (for WL#4626/4685)
+ #if (!$exiting && ($signal_num == 2 || $signal_num == 15 ||
+ # ($opt_abort_on_error && $env->{errors}->{S1} > 0)))
+ if (!$exiting && ($signal_num == 2 || $signal_num == 15))
{
- #mysqltest was interrupted with INT or TERM signals or test was
- #ran with --abort-on-error option and we got errors with severity S1
+ #mysqltest was interrupted with INT or TERM signals
#so we assume that we should cancel testing and exit
$exiting=1;
+ # OBN - Adjusted text to exclude case of S1 and abort-on-error that
+ # was mentioned (for WL#4626/4685)
print STDERR<<EOF;
WARNING:
- mysqltest was interrupted with INT or TERM signals or test was
- ran with --abort-on-error option and we got errors with severity S1
- (test cann't connect to the server or server crashed) so we assume that
+ mysqltest was interrupted with INT or TERM signals so we assume that
we should cancel testing and exit. Please check log file for this thread
in $stress_log_file or
inspect below output of the last test case executed with mysqltest to
@@ -840,12 +895,23 @@ LOOP:
$client_env{test_count}."]:".
" TID ".$client_env{thread_id}.
" test: '$test_name' ".
- " Errors: ".join(" ",@{$client_env{test_status}}),"\n";
- print "\n";
+ " Errors: ".join(" ",@{$client_env{test_status}}).
+ ( $exiting ? " (thread aborting)" : "" )."\n";
}
- sleep($opt_sleep_time) if($opt_sleep_time);
-
+ # OBN - At this point we need to wait until the 'wait' time between test
+ # executions passes (in case it is specifed) passes, hoever we need
+ # to be able to quit and break out of the test if an 'abort-on-error'
+ # condition has happend with one of the other children (WL#4685).
+ # Using solution by ES and replacing the 'sleep' command with a loop
+ # checking the abort condition every second
+
+ if ( $opt_sleep_time ) {
+ foreach ( 1..$opt_sleep_time ) {
+ last if $exiting;
+ sleep 1;
+ }
+ }
}
}
@@ -1119,6 +1185,9 @@ mysql-stress-test.pl --stress-basedir=<dir> --stress-suite-basedir=<dir> --serve
--cleanup
Force to clean up working directory (specified with --stress-basedir)
+--abort-on-error=<number>
+ Causes the script to abort if an error with severity <= number was encounterd
+
--log-error-details
Enable errors details in the global error log file. (Default: off)
diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result
index eb93c69d960..0124a7da35a 100644
--- a/mysql-test/r/delete.result
+++ b/mysql-test/r/delete.result
@@ -279,3 +279,48 @@ ERROR 42000: Incorrect number of arguments for FUNCTION test.f1; expected 0, got
DROP TABLE t1;
DROP FUNCTION f1;
End of 5.0 tests
+#
+# Bug#46958: Assertion in Diagnostics_area::set_ok_status, trigger,
+# merge table
+#
+CREATE TABLE t1 ( a INT );
+CREATE TABLE t2 ( a INT );
+CREATE TABLE t3 ( a INT );
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1), (2);
+INSERT INTO t3 VALUES (1), (2);
+CREATE TRIGGER tr1 BEFORE DELETE ON t2
+FOR EACH ROW INSERT INTO no_such_table VALUES (1);
+DELETE t1, t2, t3 FROM t1, t2, t3;
+ERROR 42S02: Table 'test.no_such_table' doesn't exist
+SELECT * FROM t1;
+a
+SELECT * FROM t2;
+a
+1
+2
+SELECT * FROM t3;
+a
+1
+2
+DROP TABLE t1, t2, t3;
+CREATE TABLE t1 ( a INT );
+CREATE TABLE t2 ( a INT );
+CREATE TABLE t3 ( a INT );
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1), (2);
+INSERT INTO t3 VALUES (1), (2);
+CREATE TRIGGER tr1 AFTER DELETE ON t2
+FOR EACH ROW INSERT INTO no_such_table VALUES (1);
+DELETE t1, t2, t3 FROM t1, t2, t3;
+ERROR 42S02: Table 'test.no_such_table' doesn't exist
+SELECT * FROM t1;
+a
+SELECT * FROM t2;
+a
+2
+SELECT * FROM t3;
+a
+1
+2
+DROP TABLE t1, t2, t3;
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index 736ecf1d90e..77f73532474 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -1064,3 +1064,13 @@ a b c d
128 NULL 128 NULL
DROP TABLE IF EXISTS t1,t2;
End of 5.0 tests.
+CREATE TABLE t1 (f1 int);
+CREATE TABLE t2 (f1 int);
+INSERT INTO t2 VALUES (1);
+CREATE VIEW v1 AS SELECT * FROM t2;
+PREPARE stmt FROM 'UPDATE t2 AS A NATURAL JOIN v1 B SET B.f1 = 1';
+EXECUTE stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+DROP VIEW v1;
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result
index 68577cb2a4c..482e0045840 100644
--- a/mysql-test/r/subselect4.result
+++ b/mysql-test/r/subselect4.result
@@ -27,4 +27,35 @@ SELECT 1;
1
1
DROP TABLE t1,t2,t3;
+#
+# Bug #47106: Crash / segfault on adding EXPLAIN to a non-crashing
+# query
+#
+CREATE TABLE t1 (
+a INT,
+b INT,
+PRIMARY KEY (a),
+KEY b (b)
+);
+INSERT INTO t1 VALUES (1, 1), (2, 1);
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 SELECT * FROM t1;
+CREATE TABLE t3 LIKE t1;
+INSERT INTO t3 SELECT * FROM t1;
+# Should not crash.
+# Should have 1 impossible where and 2 dependent subqs.
+EXPLAIN
+SELECT
+(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
+FROM t3 WHERE 1 = 0 GROUP BY 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 DEPENDENT SUBQUERY t1 index NULL PRIMARY 4 NULL 2 Using index
+2 DEPENDENT SUBQUERY t2 index b b 5 NULL 2 Using where; Using index; Using join buffer
+# should return 0 rows
+SELECT
+(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
+FROM t3 WHERE 1 = 0 GROUP BY 1;
+(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
+DROP TABLE t1,t2,t3;
End of 5.0 tests.
diff --git a/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result b/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result
index 503076d66d9..0a6ff1d4400 100644
--- a/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result
+++ b/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result
@@ -1,17 +1,31 @@
-drop database if exists `drop-temp+table-test`;
-reset master;
-create database `drop-temp+table-test`;
-use `drop-temp+table-test`;
-create temporary table shortn1 (a int);
-create temporary table `table:name` (a int);
-create temporary table shortn2 (a int);
-select get_lock("a",10);
-get_lock("a",10)
+DROP DATABASE IF EXISTS `drop-temp+table-test`;
+RESET MASTER;
+CREATE DATABASE `drop-temp+table-test`;
+USE `drop-temp+table-test`;
+CREATE TEMPORARY TABLE shortn1 (a INT);
+CREATE TEMPORARY TABLE `table:name` (a INT);
+CREATE TEMPORARY TABLE shortn2 (a INT);
+CREATE TEMPORARY TABLE tmp(c1 int);
+CREATE TEMPORARY TABLE tmp1(c1 int);
+CREATE TEMPORARY TABLE tmp2(c1 int);
+CREATE TEMPORARY TABLE tmp3(c1 int);
+CREATE TABLE t(c1 int);
+DROP TEMPORARY TABLE IF EXISTS tmp;
+DROP TEMPORARY TABLE IF EXISTS tmp;
+DROP TEMPORARY TABLE IF EXISTS tmp, tmp1;
+DROP TEMPORARY TABLE tmp3;
+DROP TABLE IF EXISTS tmp2, t;
+DROP TABLE IF EXISTS tmp2, t;
+SELECT GET_LOCK("a",10);
+GET_LOCK("a",10)
1
-select get_lock("a",10);
-get_lock("a",10)
+SELECT GET_LOCK("a",10);
+GET_LOCK("a",10)
1
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # create database `drop-temp+table-test`
-drop database `drop-temp+table-test`;
+master-bin.000001 # Query # # CREATE DATABASE `drop-temp+table-test`
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TABLE t(c1 int)
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS `t` /* generated by server */
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS tmp2, t
+DROP DATABASE `drop-temp+table-test`;
diff --git a/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result b/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result
index 4d24b2409b9..8bbf1bccc63 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result
@@ -1,21 +1,43 @@
-drop database if exists `drop-temp+table-test`;
-reset master;
-create database `drop-temp+table-test`;
-use `drop-temp+table-test`;
-create temporary table shortn1 (a int);
-create temporary table `table:name` (a int);
-create temporary table shortn2 (a int);
-select get_lock("a",10);
-get_lock("a",10)
+DROP DATABASE IF EXISTS `drop-temp+table-test`;
+RESET MASTER;
+CREATE DATABASE `drop-temp+table-test`;
+USE `drop-temp+table-test`;
+CREATE TEMPORARY TABLE shortn1 (a INT);
+CREATE TEMPORARY TABLE `table:name` (a INT);
+CREATE TEMPORARY TABLE shortn2 (a INT);
+CREATE TEMPORARY TABLE tmp(c1 int);
+CREATE TEMPORARY TABLE tmp1(c1 int);
+CREATE TEMPORARY TABLE tmp2(c1 int);
+CREATE TEMPORARY TABLE tmp3(c1 int);
+CREATE TABLE t(c1 int);
+DROP TEMPORARY TABLE IF EXISTS tmp;
+DROP TEMPORARY TABLE IF EXISTS tmp;
+DROP TEMPORARY TABLE IF EXISTS tmp, tmp1;
+DROP TEMPORARY TABLE tmp3;
+DROP TABLE IF EXISTS tmp2, t;
+DROP TABLE IF EXISTS tmp2, t;
+SELECT GET_LOCK("a",10);
+GET_LOCK("a",10)
1
-select get_lock("a",10);
-get_lock("a",10)
+SELECT GET_LOCK("a",10);
+GET_LOCK("a",10)
1
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # create database `drop-temp+table-test`
-master-bin.000001 # Query # # use `drop-temp+table-test`; create temporary table shortn1 (a int)
-master-bin.000001 # Query # # use `drop-temp+table-test`; create temporary table `table:name` (a int)
-master-bin.000001 # Query # # use `drop-temp+table-test`; create temporary table shortn2 (a int)
+master-bin.000001 # Query # # CREATE DATABASE `drop-temp+table-test`
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TEMPORARY TABLE shortn1 (a INT)
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TEMPORARY TABLE `table:name` (a INT)
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TEMPORARY TABLE shortn2 (a INT)
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TEMPORARY TABLE tmp(c1 int)
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TEMPORARY TABLE tmp1(c1 int)
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TEMPORARY TABLE tmp2(c1 int)
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TEMPORARY TABLE tmp3(c1 int)
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TABLE t(c1 int)
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TEMPORARY TABLE IF EXISTS tmp
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TEMPORARY TABLE IF EXISTS tmp
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TEMPORARY TABLE IF EXISTS tmp, tmp1
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TEMPORARY TABLE tmp3
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS tmp2, t
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS tmp2, t
master-bin.000001 # Query # # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `shortn2`,`table:name`,`shortn1`
-drop database `drop-temp+table-test`;
+DROP DATABASE `drop-temp+table-test`;
diff --git a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result
index 263896b884a..ae3554a5420 100644
--- a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result
+++ b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result
@@ -4,6 +4,8 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+call mtr.add_suppression("Slave I/O: .* failed with error: Lost connection to MySQL server at 'reading initial communication packet'");
+call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again");
SELECT IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP");
IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP")
1
@@ -16,7 +18,8 @@ start slave;
SELECT RELEASE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP");
RELEASE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP")
1
-Slave_IO_Errno= 2013
+Check network error happened here
+NETWORK ERROR
SELECT IS_FREE_LOCK("debug_lock.before_get_SERVER_ID");
IS_FREE_LOCK("debug_lock.before_get_SERVER_ID")
1
@@ -29,7 +32,8 @@ start slave;
SELECT RELEASE_LOCK("debug_lock.before_get_SERVER_ID");
RELEASE_LOCK("debug_lock.before_get_SERVER_ID")
1
-Slave_IO_Errno= 2013
+Check network error happened here
+NETWORK ERROR
set global debug= '';
reset master;
include/stop_slave.inc
diff --git a/mysql-test/suite/rpl/r/rpl_log_pos.result b/mysql-test/suite/rpl/r/rpl_log_pos.result
index 7b3ebf62959..85fa4c10eac 100644
--- a/mysql-test/suite/rpl/r/rpl_log_pos.result
+++ b/mysql-test/suite/rpl/r/rpl_log_pos.result
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+call mtr.add_suppression ("Slave I/O: Got fatal error 1236 from master when reading data from binary");
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 # <Binlog_Do_DB> <Binlog_Ignore_DB>
diff --git a/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result b/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result
new file mode 100644
index 00000000000..09a9121d22c
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result
@@ -0,0 +1,13 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP DATABASE IF EXISTS `#mysql50#mysqltest-1`;
+CREATE DATABASE `#mysql50#mysqltest-1`;
+Master position is not changed
+STOP SLAVE SQL_THREAD;
+Master position has been changed
+DROP DATABASE `mysqltest-1`;
+DROP DATABASE `#mysql50#mysqltest-1`;
diff --git a/mysql-test/suite/rpl/r/rpl_packet.result b/mysql-test/suite/rpl/r/rpl_packet.result
index cb26d04bea9..0a9495751fe 100644
--- a/mysql-test/suite/rpl/r/rpl_packet.result
+++ b/mysql-test/suite/rpl/r/rpl_packet.result
@@ -4,6 +4,8 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+call mtr.add_suppression("Slave I/O: Got a packet bigger than 'max_allowed_packet' bytes, Error_code: 1153");
+call mtr.add_suppression("Slave I/O: Got fatal error 1236 from master when reading data from binary log:");
drop database if exists DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________;
create database DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________;
SET @@global.max_allowed_packet=1024;
diff --git a/mysql-test/suite/rpl/r/rpl_row_disabled_slave_key.result b/mysql-test/suite/rpl/r/rpl_row_disabled_slave_key.result
new file mode 100644
index 00000000000..01e3dfd6508
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_row_disabled_slave_key.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;
+SET SQL_LOG_BIN=0;
+CREATE TABLE t (a int, b int, c int, key(b));
+SET SQL_LOG_BIN=1;
+CREATE TABLE t (a int, b int, c int);
+INSERT INTO t VALUES (1,2,4);
+INSERT INTO t VALUES (4,3,4);
+DELETE FROM t;
+DROP TABLE t;
+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 t (a int, b int, c int, key(b));
+ALTER TABLE t DISABLE KEYS;
+INSERT INTO t VALUES (1,2,4);
+INSERT INTO t VALUES (4,3,4);
+DELETE FROM t;
+DROP TABLE t;
diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def
index 38fc9e21322..8cae44a3607 100644
--- a/mysql-test/suite/rpl/t/disabled.def
+++ b/mysql-test/suite/rpl/t/disabled.def
@@ -10,4 +10,3 @@
#
##############################################################################
-rpl_cross_version : Bug#42311 2009-03-27 joro rpl_cross_version fails on macosx
diff --git a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
index 40d11f2cec2..a391b1f5344 100644
--- a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
+++ b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
@@ -16,6 +16,8 @@
source include/master-slave.inc;
source include/have_debug.inc;
+call mtr.add_suppression("Slave I/O: .* failed with error: Lost connection to MySQL server at 'reading initial communication packet'");
+call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again");
#Test case 1: Try to get the value of the UNIX_TIMESTAMP from master under network disconnection
connection slave;
let $debug_saved= `select @@global.debug`;
diff --git a/mysql-test/suite/rpl/t/rpl_log_pos.test b/mysql-test/suite/rpl/t/rpl_log_pos.test
index 5e8390f97ed..48effa00b64 100644
--- a/mysql-test/suite/rpl/t/rpl_log_pos.test
+++ b/mysql-test/suite/rpl/t/rpl_log_pos.test
@@ -11,6 +11,7 @@
# Passes with rbr no problem, removed statement include [jbm]
source include/master-slave.inc;
+call mtr.add_suppression ("Slave I/O: Got fatal error 1236 from master when reading data from binary");
source include/show_master_status.inc;
sync_slave_with_master;
source include/stop_slave.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test b/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test
new file mode 100644
index 00000000000..bf5c6d2b921
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test
@@ -0,0 +1,56 @@
+#############################################################################
+# BUG#43579 mysql_upgrade tries to alter log tables on replicated database
+# Master and slave should be upgraded separately. All statements executed by
+# mysql_upgrade will not be binlogged. --write-binlog and --skip-write-binlog
+# options are added into mysql_upgrade. These options control whether sql
+# statements are binlogged or not.
+#############################################################################
+--source include/master-slave.inc
+
+# Only run test if "mysql_upgrade" is found
+--source include/have_mysql_upgrade.inc
+
+connection master;
+--disable_warnings
+DROP DATABASE IF EXISTS `#mysql50#mysqltest-1`;
+CREATE DATABASE `#mysql50#mysqltest-1`;
+--enable_warnings
+sync_slave_with_master;
+
+connection master;
+let $before_position= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+#With '--force' option, mysql_upgrade always executes all sql statements for upgrading.
+#--skip-write-binlog option disables binlog.
+--exec $MYSQL_UPGRADE --skip-write-binlog --skip-verbose --force --user=root > $MYSQLTEST_VARDIR/log/mysql_upgrade.log 2>&1
+sync_slave_with_master;
+
+connection master;
+let $after_position= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+if (`SELECT '$before_position'='$after_position'`)
+{
+ echo Master position is not changed;
+}
+
+#Some log events of the mysql_upgrade's will cause errors on slave.
+connection slave;
+STOP SLAVE SQL_THREAD;
+source include/wait_for_slave_sql_to_stop.inc;
+
+connection master;
+#With '--force' option, mysql_upgrade always executes all sql statements for upgrading.
+--exec $MYSQL_UPGRADE --skip-verbose --force --user=root > $MYSQLTEST_VARDIR/log/mysql_upgrade.log 2>&1
+
+connection master;
+let $after_file= query_get_value(SHOW MASTER STATUS, File, 1);
+let $after_position= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+if (!`SELECT '$before_position'='$after_position'`)
+{
+ echo Master position has been changed;
+}
+
+DROP DATABASE `mysqltest-1`;
+connection slave;
+DROP DATABASE `#mysql50#mysqltest-1`;
diff --git a/mysql-test/suite/rpl/t/rpl_packet.test b/mysql-test/suite/rpl/t/rpl_packet.test
index b4e04405037..bfc144c759b 100644
--- a/mysql-test/suite/rpl/t/rpl_packet.test
+++ b/mysql-test/suite/rpl/t/rpl_packet.test
@@ -6,6 +6,8 @@
# max-out size db name
source include/master-slave.inc;
source include/have_binlog_format_row.inc;
+call mtr.add_suppression("Slave I/O: Got a packet bigger than 'max_allowed_packet' bytes, Error_code: 1153");
+call mtr.add_suppression("Slave I/O: Got fatal error 1236 from master when reading data from binary log:");
let $db= DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________;
disable_warnings;
diff --git a/mysql-test/suite/rpl/t/rpl_row_disabled_slave_key.test b/mysql-test/suite/rpl/t/rpl_row_disabled_slave_key.test
new file mode 100644
index 00000000000..1d7e134f4f4
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_disabled_slave_key.test
@@ -0,0 +1,73 @@
+# BUG#47312: RBR: Disabling key on slave breaks replication:
+# HA_ERR_WRONG_INDEX
+#
+# Description
+# ===========
+#
+# This test case checks whether disabling a key on a slave breaks
+# replication or not.
+#
+# Case #1, shows that while not using ALTER TABLE... DISABLE KEYS and
+# the slave has no key defined while the master has one, replication
+# won't break.
+#
+# Case #2, shows that before patch for BUG#47312, if defining key on
+# slave table, and later disable it, replication would break. This
+# has been fixed.
+#
+
+-- source include/master-slave.inc
+-- source include/have_binlog_format_row.inc
+
+#
+# Case #1: master has key, but slave has not.
+# Replication does not break.
+#
+
+SET SQL_LOG_BIN=0;
+CREATE TABLE t (a int, b int, c int, key(b));
+SET SQL_LOG_BIN=1;
+
+-- connection slave
+
+CREATE TABLE t (a int, b int, c int);
+
+-- connection master
+
+INSERT INTO t VALUES (1,2,4);
+INSERT INTO t VALUES (4,3,4);
+DELETE FROM t;
+
+-- sync_slave_with_master
+
+-- connection master
+DROP TABLE t;
+
+-- sync_slave_with_master
+
+#
+# Case #2: master has key, slave also has one,
+# but it gets disabled sometime.
+# Replication does not break anymore.
+#
+-- source include/master-slave-reset.inc
+-- connection master
+
+CREATE TABLE t (a int, b int, c int, key(b));
+
+-- sync_slave_with_master
+
+ALTER TABLE t DISABLE KEYS;
+
+-- connection master
+
+INSERT INTO t VALUES (1,2,4);
+INSERT INTO t VALUES (4,3,4);
+DELETE FROM t;
+
+-- sync_slave_with_master
+
+-- connection master
+DROP TABLE t;
+
+-- sync_slave_with_master
diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test
index 602e30687c8..d77f5eb128b 100644
--- a/mysql-test/t/delete.test
+++ b/mysql-test/t/delete.test
@@ -292,3 +292,47 @@ DROP TABLE t1;
DROP FUNCTION f1;
--echo End of 5.0 tests
+
+--echo #
+--echo # Bug#46958: Assertion in Diagnostics_area::set_ok_status, trigger,
+--echo # merge table
+--echo #
+CREATE TABLE t1 ( a INT );
+CREATE TABLE t2 ( a INT );
+CREATE TABLE t3 ( a INT );
+
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1), (2);
+INSERT INTO t3 VALUES (1), (2);
+
+CREATE TRIGGER tr1 BEFORE DELETE ON t2
+FOR EACH ROW INSERT INTO no_such_table VALUES (1);
+
+--error ER_NO_SUCH_TABLE
+DELETE t1, t2, t3 FROM t1, t2, t3;
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+SELECT * FROM t3;
+
+DROP TABLE t1, t2, t3;
+
+CREATE TABLE t1 ( a INT );
+CREATE TABLE t2 ( a INT );
+CREATE TABLE t3 ( a INT );
+
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1), (2);
+INSERT INTO t3 VALUES (1), (2);
+
+CREATE TRIGGER tr1 AFTER DELETE ON t2
+FOR EACH ROW INSERT INTO no_such_table VALUES (1);
+
+--error ER_NO_SUCH_TABLE
+DELETE t1, t2, t3 FROM t1, t2, t3;
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+SELECT * FROM t3;
+
+DROP TABLE t1, t2, t3;
diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test
index b5e30e63f54..1cd05c8cb65 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -729,4 +729,24 @@ SELECT * FROM t1 JOIN t2 ON b=c ORDER BY a;
SELECT * FROM t1 JOIN t2 ON a=c ORDER BY a;
DROP TABLE IF EXISTS t1,t2;
+
--echo End of 5.0 tests.
+
+
+#
+# Bug#47150 Assertion in Field_long::val_int() on MERGE + TRIGGER + multi-table UPDATE
+#
+CREATE TABLE t1 (f1 int);
+
+CREATE TABLE t2 (f1 int);
+INSERT INTO t2 VALUES (1);
+CREATE VIEW v1 AS SELECT * FROM t2;
+
+PREPARE stmt FROM 'UPDATE t2 AS A NATURAL JOIN v1 B SET B.f1 = 1';
+EXECUTE stmt;
+EXECUTE stmt;
+
+DEALLOCATE PREPARE stmt;
+
+DROP VIEW v1;
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test
index ff4cdf3c439..440eca22828 100644
--- a/mysql-test/t/subselect4.test
+++ b/mysql-test/t/subselect4.test
@@ -28,5 +28,37 @@ SELECT 1;
DROP TABLE t1,t2,t3;
+--echo #
+--echo # Bug #47106: Crash / segfault on adding EXPLAIN to a non-crashing
+--echo # query
+--echo #
+
+CREATE TABLE t1 (
+ a INT,
+ b INT,
+ PRIMARY KEY (a),
+ KEY b (b)
+);
+INSERT INTO t1 VALUES (1, 1), (2, 1);
+
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 SELECT * FROM t1;
+
+CREATE TABLE t3 LIKE t1;
+INSERT INTO t3 SELECT * FROM t1;
+
+--echo # Should not crash.
+--echo # Should have 1 impossible where and 2 dependent subqs.
+EXPLAIN
+SELECT
+ (SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
+FROM t3 WHERE 1 = 0 GROUP BY 1;
+
+--echo # should return 0 rows
+SELECT
+ (SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
+FROM t3 WHERE 1 = 0 GROUP BY 1;
+
+DROP TABLE t1,t2,t3;
--echo End of 5.0 tests.
diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp
index 21c6c30abcc..6b10e4cb544 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -1,4 +1,3 @@
-#
# Suppress some common (not fatal) errors in system libraries found by valgrind
#
@@ -625,3 +624,101 @@
fun:start_thread
}
+# suppressions for glibc 2.6.1 64 bit
+
+{
+ Mem loss within nptl_pthread_exit_hack_handler 6
+ Memcheck:Leak
+ fun:malloc
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ fun:__libc_dlopen_mode
+ fun:pthread_cancel_init
+ fun:_Unwind_ForcedUnwind
+ fun:__pthread_unwind
+ fun:pthread_exit
+ fun:nptl_pthread_exit_hack_handler
+}
+
+{
+ Mem loss within nptl_pthread_exit_hack_handler 7
+ Memcheck:Leak
+ fun:malloc
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ fun:__libc_dlopen_mode
+ fun:pthread_cancel_init
+ fun:_Unwind_ForcedUnwind
+ fun:__pthread_unwind
+ fun:pthread_exit
+ fun:nptl_pthread_exit_hack_handler
+ fun:start_thread
+ fun:clone
+}
+
+{
+ Mem loss within nptl_pthread_exit_hack_handler 8
+ Memcheck:Leak
+ fun:calloc
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ fun:__libc_dlopen_mode
+ fun:pthread_cancel_init
+ fun:_Unwind_ForcedUnwind
+ fun:__pthread_unwind
+ fun:pthread_exit
+ fun:nptl_pthread_exit_hack_handler
+ fun:start_thread
+ fun:clone
+}
+
+{
+ Mem loss within nptl_pthread_exit_hack_handler 8
+ Memcheck:Leak
+ fun:calloc
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ fun:__libc_dlopen_mode
+ fun:pthread_cancel_init
+ fun:_Unwind_ForcedUnwind
+ fun:__pthread_unwind
+ fun:pthread_exit
+ fun:nptl_pthread_exit_hack_handler
+}
+
+#
+# Pthread doesn't free all thread specific memory before program exists
+#
+{
+ pthread allocate_tls memory loss in 2.6.1.
+ Memcheck:Leak
+ fun:calloc
+ obj:*/ld-*.so
+ fun:_dl_allocate_tls
+ fun:pthread_create*
+}
+
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 2278c467f32..d8c7d85ff30 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -108,10 +108,11 @@ my_bool my_thread_global_init(void)
pthread_attr_t dummy_thread_attr;
pthread_attr_init(&dummy_thread_attr);
- pthread_attr_setdetachstate(&dummy_thread_attr, PTHREAD_CREATE_DETACHED);
+ pthread_attr_setdetachstate(&dummy_thread_attr, PTHREAD_CREATE_JOINABLE);
- pthread_create(&dummy_thread,&dummy_thread_attr,
- nptl_pthread_exit_hack_handler, NULL);
+ if (pthread_create(&dummy_thread,&dummy_thread_attr,
+ nptl_pthread_exit_hack_handler, NULL) == 0)
+ (void)pthread_join(dummy_thread, NULL);
}
#endif /* TARGET_OS_LINUX */
diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc
index 58ec4af7841..9e7141b775b 100644
--- a/sql/debug_sync.cc
+++ b/sql/debug_sync.cc
@@ -699,7 +699,7 @@ static void debug_sync_print_actions(THD *thd)
DBUG_ASSERT(thd);
if (!ds_control)
- return;
+ DBUG_VOID_RETURN;
for (idx= 0; idx < ds_control->ds_active; idx++)
{
diff --git a/sql/item.cc b/sql/item.cc
index 26df3a45971..86e4551e55b 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -6331,9 +6331,26 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
/* view fild reference must be defined */
DBUG_ASSERT(*ref);
/* (*ref)->check_cols() will be made in Item_direct_ref::fix_fields */
- if (!(*ref)->fixed &&
- ((*ref)->fix_fields(thd, ref)))
+ if ((*ref)->fixed)
+ {
+ Item *ref_item= (*ref)->real_item();
+ if (ref_item->type() == Item::FIELD_ITEM)
+ {
+ /*
+ In some cases we need to update table read set(see bug#47150).
+ If ref item is FIELD_ITEM and fixed then field and table
+ have proper values. So we can use them for update.
+ */
+ Field *fld= ((Item_field*) ref_item)->field;
+ DBUG_ASSERT(fld && fld->table);
+ if (thd->mark_used_columns == MARK_COLUMNS_READ)
+ bitmap_set_bit(fld->table->read_set, fld->field_index);
+ }
+ }
+ else if (!(*ref)->fixed &&
+ ((*ref)->fix_fields(thd, ref)))
return TRUE;
+
return Item_direct_ref::fix_fields(thd, reference);
}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index a85e354b786..d9e6f76dd6b 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -4235,7 +4235,7 @@ void Item_func_set_user_var::save_item_result(Item *item)
bool
Item_func_set_user_var::update()
{
- bool res= NULL;
+ bool res= 0;
DBUG_ENTER("Item_func_set_user_var::update");
switch (cached_result_type) {
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 08fe3aba8ed..3c584011bfb 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -8835,11 +8835,11 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
*/
store_record(table,record[1]);
- if (table->s->keys > 0)
+ if (table->s->keys > 0 && table->s->keys_in_use.is_set(0))
{
DBUG_PRINT("info",("locating record using primary key (index_read)"));
- /* We have a key: search the table using the index */
+ /* The 0th key is active: 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));
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 27b59bde7be..024a6587b43 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -2912,7 +2912,8 @@ public:
bool send_data(List<Item> &items);
bool initialize_tables (JOIN *join);
void send_error(uint errcode,const char *err);
- int do_deletes();
+ int do_deletes();
+ int do_table_deletes(TABLE *table, bool ignore);
bool send_eof();
virtual void abort();
};
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index d2f90fa9288..a81a5f4641f 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -860,22 +860,19 @@ void multi_delete::abort()
-/*
+/**
Do delete from other tables.
- Returns values:
- 0 ok
- 1 error
+
+ @retval 0 ok
+ @retval 1 error
+
+ @todo Is there any reason not use the normal nested-loops join? If not, and
+ there is no documentation supporting it, this method and callee should be
+ removed and there should be hooks within normal execution.
*/
int multi_delete::do_deletes()
{
- int local_error= 0, counter= 0, tmp_error;
- bool will_batch;
- /*
- If the IGNORE option is used all non fatal errors will be translated
- to warnings and we should not break the row-by-row iteration
- */
- bool ignore= thd->lex->current_select->no_error;
DBUG_ENTER("do_deletes");
DBUG_ASSERT(do_delete);
@@ -886,79 +883,108 @@ int multi_delete::do_deletes()
table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
delete_tables);
- for (; table_being_deleted;
+ for (uint counter= 0; table_being_deleted;
table_being_deleted= table_being_deleted->next_local, counter++)
{
- ha_rows last_deleted= deleted;
TABLE *table = table_being_deleted->table;
if (tempfiles[counter]->get(table))
+ DBUG_RETURN(1);
+
+ int local_error=
+ do_table_deletes(table, thd->lex->current_select->no_error);
+
+ if (thd->killed && !local_error)
+ DBUG_RETURN(1);
+
+ if (local_error == -1) // End of file
+ local_error = 0;
+
+ if (local_error)
+ DBUG_RETURN(local_error);
+ }
+ DBUG_RETURN(0);
+}
+
+
+/**
+ Implements the inner loop of nested-loops join within multi-DELETE
+ execution.
+
+ @param table The table from which to delete.
+
+ @param ignore If used, all non fatal errors will be translated
+ to warnings and we should not break the row-by-row iteration.
+
+ @return Status code
+
+ @retval 0 All ok.
+ @retval 1 Triggers or handler reported error.
+ @retval -1 End of file from handler.
+*/
+int multi_delete::do_table_deletes(TABLE *table, bool ignore)
+{
+ int local_error= 0;
+ READ_RECORD info;
+ ha_rows last_deleted= deleted;
+ DBUG_ENTER("do_deletes_for_table");
+ init_read_record(&info, thd, table, NULL, 0, 1, FALSE);
+ /*
+ Ignore any rows not found in reference tables as they may already have
+ been deleted by foreign key handling
+ */
+ info.ignore_not_found_rows= 1;
+ bool will_batch= !table->file->start_bulk_delete();
+ while (!(local_error= info.read_record(&info)) && !thd->killed)
+ {
+ if (table->triggers &&
+ table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
+ TRG_ACTION_BEFORE, FALSE))
{
- local_error=1;
+ local_error= 1;
break;
}
-
- READ_RECORD info;
- init_read_record(&info, thd, table, NULL, 0, 1, FALSE);
+
+ local_error= table->file->ha_delete_row(table->record[0]);
+ if (local_error && !ignore)
+ {
+ table->file->print_error(local_error, MYF(0));
+ break;
+ }
+
/*
- Ignore any rows not found in reference tables as they may already have
- been deleted by foreign key handling
+ Increase the reported number of deleted rows only if no error occurred
+ during ha_delete_row.
+ Also, don't execute the AFTER trigger if the row operation failed.
*/
- info.ignore_not_found_rows= 1;
- will_batch= !table->file->start_bulk_delete();
- while (!(local_error=info.read_record(&info)) && !thd->killed)
+ if (!local_error)
{
+ deleted++;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
- TRG_ACTION_BEFORE, FALSE))
+ TRG_ACTION_AFTER, FALSE))
{
local_error= 1;
break;
}
-
- local_error= table->file->ha_delete_row(table->record[0]);
- if (local_error && !ignore)
- {
- table->file->print_error(local_error,MYF(0));
- break;
- }
-
- /*
- Increase the reported number of deleted rows only if no error occurred
- during ha_delete_row.
- Also, don't execute the AFTER trigger if the row operation failed.
- */
- if (!local_error)
- {
- deleted++;
- if (table->triggers &&
- table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
- TRG_ACTION_AFTER, FALSE))
- {
- local_error= 1;
- break;
- }
- }
}
- if (will_batch && (tmp_error= table->file->end_bulk_delete()))
+ }
+ if (will_batch)
+ {
+ int tmp_error= table->file->end_bulk_delete();
+ if (tmp_error && !local_error)
{
- if (!local_error)
- {
- local_error= tmp_error;
- table->file->print_error(local_error,MYF(0));
- }
+ local_error= tmp_error;
+ table->file->print_error(local_error, MYF(0));
}
- if (last_deleted != deleted && !table->file->has_transactions())
- thd->transaction.stmt.modified_non_trans_table= TRUE;
- end_read_record(&info);
- if (thd->killed && !local_error)
- local_error= 1;
- if (local_error == -1) // End of file
- local_error = 0;
}
+ if (last_deleted != deleted && !table->file->has_transactions())
+ thd->transaction.stmt.modified_non_trans_table= TRUE;
+
+ end_read_record(&info);
+
DBUG_RETURN(local_error);
}
-
/*
Send ok to the client
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 1ff068c8881..3f1432914a0 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3308,12 +3308,12 @@ add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
@retval FALSE it's something else
*/
-inline static bool
+static bool
is_local_field (Item *field)
{
- field= field->real_item();
- return field->type() == Item::FIELD_ITEM &&
- !((Item_field *)field)->depended_from;
+ return field->real_item()->type() == Item::FIELD_ITEM
+ && !(field->used_tables() & OUTER_REF_TABLE_BIT)
+ && !((Item_field *)field->real_item())->depended_from;
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 08f3311be9d..6dba2f02071 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1949,7 +1949,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
being built. The string always end in a comma and the comma
will be chopped off before being written to the binary log.
*/
- if (thd->current_stmt_binlog_row_based && !dont_log_query)
+ if (!drop_temporary && thd->current_stmt_binlog_row_based && !dont_log_query)
{
non_temp_tables_count++;
/*
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index 15eb28e6183..1c33ffa90f5 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -801,7 +801,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
{
DBUG_DUMP("old",(uchar*) info->lastkey, info->lastkey_length);
DBUG_DUMP("new",(uchar*) key, key_length);
- DBUG_DUMP("new_in_page",(char*) old_keypos,(uint) (keypos-old_keypos));
+ DBUG_DUMP("new_in_page",(uchar*) old_keypos,(uint) (keypos-old_keypos));
if (comp_flag & SEARCH_FIND && flag == 0)
mi_check_print_error(param,"Found duplicated key at page %s",llstr(page,llbuff));
@@ -871,7 +871,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
llstr(page,llbuff),llstr(record,llbuff2),
llstr(info->state->data_file_length,llbuff3)));
DBUG_DUMP("key",(uchar*) key,key_length);
- DBUG_DUMP("new_in_page",(char*) old_keypos,(uint) (keypos-old_keypos));
+ DBUG_DUMP("new_in_page",(uchar*) old_keypos,(uint) (keypos-old_keypos));
goto err;
}
param->record_checksum+=(ha_checksum) record;
@@ -1545,6 +1545,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
param->testflag|=T_CALC_CHECKSUM;
+ DBUG_ASSERT(param->use_buffers < SIZE_T_MAX);
+
if (!param->using_global_keycache)
VOID(init_key_cache(dflt_key_cache, param->key_cache_block_size,
(size_t) param->use_buffers, 0, 0));
diff --git a/support-files/binary-configure.sh b/support-files/binary-configure.sh
index 884a8363e22..5e6d62f69a0 100644
--- a/support-files/binary-configure.sh
+++ b/support-files/binary-configure.sh
@@ -1,4 +1,28 @@
#!/bin/sh
+
+SCRIPT_NAME="`basename $0`"
+
+usage()
+{
+ echo "Usage: ${SCRIPT_NAME} [--help|-h]"
+ echo ""
+ echo "This script creates the MySQL system tables and starts the server."
+}
+
+for arg do
+ case "$arg" in
+ --help|-h)
+ usage
+ exit 0
+ ;;
+ *)
+ echo "${SCRIPT_NAME}: unknown option $arg"
+ usage
+ exit 2
+ ;;
+ esac
+done
+
if test ! -x ./scripts/mysql_install_db
then
echo "I didn't find the script './scripts/mysql_install_db'."