ALT Linux repositórios
S: | 8.0.30-alt2 |
5.0: | 5.0.89-alt1 |
4.1: | 5.0.51-alt2.a |
4.0: | 5.0.51-alt2.a.M40.2 |
+updates: | 5.0.51-alt2.a.M40.1 |
3.0: | 4.0.24-alt1 |
Group :: Banco de dados
RPM: MySQL
Main Changelog Spec Patches Sources Download Gear Bugs e FR Repocop
Patch: mysql-5.0.67-deb-upstream_bug_23921.patch
Download
Download
#! /bin/sh /usr/share/dpatch/dpatch-run
## 90_upstream_bug_23921.dpatch by Kees Cook <kees@ubuntu.com>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: Backported fixes for upstream bug http://bugs.mysql.com/bug.php?id=23921
## DP: http://lists.mysql.com/commits/49751
@DPATCH@
diff -urNad mysql-dfsg-5.0-5.0.67~/client/mysqltest.c mysql-dfsg-5.0-5.0.67/client/mysqltest.c
--- mysql-dfsg-5.0-5.0.67~/client/mysqltest.c 2008-08-04 05:19:05.000000000 -0700
+++ mysql-dfsg-5.0-5.0.67/client/mysqltest.c 2008-08-27 13:15:25.000000000 -0700
@@ -177,6 +177,8 @@
static ulonglong progress_start= 0;
+static ulong connection_retry_sleep= 100000; /* Microseconds */
+
/* Precompiled re's */
static my_regex_t ps_re; /* the query can be run using PS protocol */
static my_regex_t sp_re; /* the query can be run as a SP */
@@ -496,6 +498,9 @@
void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val);
void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input);
+static int match_expected_error(struct st_command *command,
+ unsigned int err_errno,
+ const char *err_sqlstate);
void handle_error(struct st_command*,
unsigned int err_errno, const char *err_error,
const char *err_sqlstate, DYNAMIC_STRING *ds);
@@ -849,29 +854,25 @@
DBUG_VOID_RETURN;
}
-
void handle_command_error(struct st_command *command, uint error)
{
DBUG_ENTER("handle_command_error");
DBUG_PRINT("enter", ("error: %d", error));
if (error != 0)
{
- uint i;
+ int i;
if (command->abort_on_error)
die("command \"%.*s\" failed with error %d",
command->first_word_len, command->query, error);
- for (i= 0; i < command->expected_errors.count; i++)
+
+ i= match_expected_error(command, error, NULL);
+
+ if (i >= 0)
{
- DBUG_PRINT("info", ("expected error: %d",
- command->expected_errors.err[i].code.errnum));
- if ((command->expected_errors.err[i].type == ERR_ERRNO) &&
- (command->expected_errors.err[i].code.errnum == error))
- {
- DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %d",
- command->first_word_len, command->query, error));
- DBUG_VOID_RETURN;
- }
+ DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %d",
+ command->first_word_len, command->query, error));
+ DBUG_VOID_RETURN;
}
die("command \"%.*s\" failed with wrong error: %d",
command->first_word_len, command->query, error);
@@ -2451,8 +2452,8 @@
error= pclose(res_file);
if (error > 0)
{
- uint status= WEXITSTATUS(error), i;
- my_bool ok= 0;
+ uint status= WEXITSTATUS(error);
+ int i;
if (command->abort_on_error)
{
@@ -2463,21 +2464,18 @@
DBUG_PRINT("info",
("error: %d, status: %d", error, status));
- for (i= 0; i < command->expected_errors.count; i++)
+
+ i= match_expected_error(command, status, NULL);
+
+ if (i >= 0)
+ DBUG_PRINT("info", ("command \"%s\" failed with expected error: %d",
+ command->first_argument, status));
+ else
{
- DBUG_PRINT("info", ("expected error: %d",
- command->expected_errors.err[i].code.errnum));
- if ((command->expected_errors.err[i].type == ERR_ERRNO) &&
- (command->expected_errors.err[i].code.errnum == status))
- {
- ok= 1;
- DBUG_PRINT("info", ("command \"%s\" failed with expected error: %d",
- command->first_argument, status));
- }
- }
- if (!ok)
+ dynstr_free(&ds_cmd);
die("command \"%s\" failed with wrong error: %d",
command->first_argument, status);
+ }
}
else if (command->expected_errors.err[0].type == ERR_ERRNO &&
command->expected_errors.err[0].code.errnum != 0)
@@ -4143,7 +4141,6 @@
int port, const char *sock)
{
int failed_attempts= 0;
- static ulong connection_retry_sleep= 100000; /* Microseconds */
DBUG_ENTER("safe_connect");
while(!mysql_real_connect(mysql, host,user, pass, db, port, sock,
@@ -4210,6 +4207,7 @@
const char* db, int port, const char* sock)
{
DYNAMIC_STRING *ds;
+ int failed_attempts= 0;
ds= &ds_res;
@@ -4238,9 +4236,42 @@
dynstr_append_mem(ds, delimiter, delimiter_length);
dynstr_append_mem(ds, "\n", 1);
}
- if (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0,
+ while (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0,
CLIENT_MULTI_STATEMENTS))
{
+ /*
+ If we have used up all our connections check whether this
+ is expected (by --error). If so, handle the error right away.
+ Otherwise, give it some extra time to rule out race-conditions.
+ If extra-time doesn't help, we have an unexpected error and
+ must abort -- just proceeding to handle_error() when second
+ and third chances are used up will handle that for us.
+
+ There are various user-limits of which only max_user_connections
+ and max_connections_per_hour apply at connect time. For the
+ the second to create a race in our logic, we'd need a limits
+ test that runs without a FLUSH for longer than an hour, so we'll
+ stay clear of trying to work out which exact user-limit was
+ exceeded.
+ */
+
+ if (((mysql_errno(con) == ER_TOO_MANY_USER_CONNECTIONS) ||
+ (mysql_errno(con) == ER_USER_LIMIT_REACHED)) &&
+ (failed_attempts++ < opt_max_connect_retries))
+ {
+ int i;
+
+ i= match_expected_error(command, mysql_errno(con), mysql_sqlstate(con));
+
+ if (i >= 0)
+ goto do_handle_error; /* expected error, handle */
+
+ my_sleep(connection_retry_sleep); /* unexpected error, wait */
+ continue; /* and give it 1 more chance */
+ }
+
+do_handle_error:
+ var_set_errno(mysql_errno(con));
handle_error(command, mysql_errno(con), mysql_error(con),
mysql_sqlstate(con), ds);
return 0; /* Not connected */
@@ -5979,6 +6010,56 @@
/*
+ Check whether given error is in list of expected errors
+
+ SYNOPSIS
+ match_expected_error()
+
+ PARAMETERS
+ command the current command (and its expect-list)
+ err_errno error number of the error that actually occurred
+ err_sqlstate SQL-state that was thrown, or NULL for impossible
+ (file-ops, diff, etc.)
+
+ RETURNS
+ -1 for not in list, index in list of expected errors otherwise
+
+ NOTE
+ If caller needs to know whether the list was empty, they should
+ check command->expected_errors.count.
+*/
+
+static int match_expected_error(struct st_command *command,
+ unsigned int err_errno,
+ const char *err_sqlstate)
+{
+ uint i;
+
+ for (i= 0 ; (uint) i < command->expected_errors.count ; i++)
+ {
+ if ((command->expected_errors.err[i].type == ERR_ERRNO) &&
+ (command->expected_errors.err[i].code.errnum == err_errno))
+ return i;
+
+ if (command->expected_errors.err[i].type == ERR_SQLSTATE)
+ {
+ /*
+ NULL is quite likely, but not in conjunction with a SQL-state expect!
+ */
+ if (unlikely(err_sqlstate == NULL))
+ die("expecting a SQL-state (%s) from query '%s' which cannot produce one...",
+ command->expected_errors.err[i].code.sqlstate, command->query);
+
+ if (strncmp(command->expected_errors.err[i].code.sqlstate,
+ err_sqlstate, SQLSTATE_LENGTH) == 0)
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+/*
Handle errors which occurred during execution
SYNOPSIS
@@ -6001,7 +6082,7 @@
unsigned int err_errno, const char *err_error,
const char *err_sqlstate, DYNAMIC_STRING *ds)
{
- uint i;
+ int i;
DBUG_ENTER("handle_error");
@@ -6027,34 +6108,30 @@
DBUG_PRINT("info", ("expected_errors.count: %d",
command->expected_errors.count));
- for (i= 0 ; (uint) i < command->expected_errors.count ; i++)
+
+ i= match_expected_error(command, err_errno, err_sqlstate);
+
+ if (i >= 0)
{
- if (((command->expected_errors.err[i].type == ERR_ERRNO) &&
- (command->expected_errors.err[i].code.errnum == err_errno)) ||
- ((command->expected_errors.err[i].type == ERR_SQLSTATE) &&
- (strncmp(command->expected_errors.err[i].code.sqlstate,
- err_sqlstate, SQLSTATE_LENGTH) == 0)))
+ if (!disable_result_log)
{
- if (!disable_result_log)
+ if (command->expected_errors.count == 1)
{
- if (command->expected_errors.count == 1)
- {
- /* Only log error if there is one possible error */
- dynstr_append_mem(ds, "ERROR ", 6);
- replace_dynstr_append(ds, err_sqlstate);
- dynstr_append_mem(ds, ": ", 2);
- replace_dynstr_append(ds, err_error);
- dynstr_append_mem(ds,"\n",1);
- }
- /* Don't log error if we may not get an error */
- else if (command->expected_errors.err[0].type == ERR_SQLSTATE ||
- (command->expected_errors.err[0].type == ERR_ERRNO &&
- command->expected_errors.err[0].code.errnum != 0))
- dynstr_append(ds,"Got one of the listed errors\n");
+ /* Only log error if there is one possible error */
+ dynstr_append_mem(ds, "ERROR ", 6);
+ replace_dynstr_append(ds, err_sqlstate);
+ dynstr_append_mem(ds, ": ", 2);
+ replace_dynstr_append(ds, err_error);
+ dynstr_append_mem(ds,"\n",1);
}
- /* OK */
- DBUG_VOID_RETURN;
+ /* Don't log error if we may not get an error */
+ else if (command->expected_errors.err[0].type == ERR_SQLSTATE ||
+ (command->expected_errors.err[0].type == ERR_ERRNO &&
+ command->expected_errors.err[0].code.errnum != 0))
+ dynstr_append(ds,"Got one of the listed errors\n");
}
+ /* OK */
+ DBUG_VOID_RETURN;
}
DBUG_PRINT("info",("i: %d expected_errors: %d", i,
@@ -6069,7 +6146,7 @@
dynstr_append_mem(ds, "\n", 1);
}
- if (i)
+ if (command->expected_errors.count > 0)
{
if (command->expected_errors.err[0].type == ERR_ERRNO)
die("query '%s' failed with wrong errno %d: '%s', instead of %d...",
diff -urNad mysql-dfsg-5.0-5.0.67~/mysql-test/r/mysqltest.result mysql-dfsg-5.0-5.0.67/mysql-test/r/mysqltest.result
--- mysql-dfsg-5.0-5.0.67~/mysql-test/r/mysqltest.result 2008-08-04 05:32:17.000000000 -0700
+++ mysql-dfsg-5.0-5.0.67/mysql-test/r/mysqltest.result 2008-08-27 13:15:25.000000000 -0700
@@ -14,6 +14,7 @@
otto
1
mysqltest: At line 1: query 'select otto from (select 1 as otto) as t1' succeeded - should have failed with sqlstate 42S22...
+mysqltest: At line 1: expecting a SQL-state (00000) from query 'remove_file MYSQLTEST_VARDIR/tmp/test_nonexistent.tmp' which cannot produce one...
select friedrich from (select 1 as otto) as t1;
ERROR 42S22: Unknown column 'friedrich' in 'field list'
mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed with wrong sqlstate 42S22: 'Unknown column 'friedrich' in 'field list'', instead of 00000...
diff -urNad mysql-dfsg-5.0-5.0.67~/mysql-test/t/disabled.def mysql-dfsg-5.0-5.0.67/mysql-test/t/disabled.def
--- mysql-dfsg-5.0-5.0.67~/mysql-test/t/disabled.def 2008-08-27 13:15:24.000000000 -0700
+++ mysql-dfsg-5.0-5.0.67/mysql-test/t/disabled.def 2008-08-27 13:15:25.000000000 -0700
@@ -10,7 +10,6 @@
#
##############################################################################
-user_limits : Bug#23921 random failure of user_limits.test
im_life_cycle : Bug#27851: Instance manager test im_life_cycle fails randomly
im_daemon_life_cycle : Bug#20294: Instance manager tests fail randomly
im_options_set : Bug#20294: Instance manager tests fail randomly
diff -urNad mysql-dfsg-5.0-5.0.67~/mysql-test/t/mysqltest.test mysql-dfsg-5.0-5.0.67/mysql-test/t/mysqltest.test
--- mysql-dfsg-5.0-5.0.67~/mysql-test/t/mysqltest.test 2008-08-04 05:32:17.000000000 -0700
+++ mysql-dfsg-5.0-5.0.67/mysql-test/t/mysqltest.test 2008-08-27 13:16:00.000000000 -0700
@@ -91,6 +91,9 @@
--error 1
--exec echo "error S42S22; select otto from (select 1 as otto) as t1;" | $MYSQL_TEST 2>&1
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--error 1
+--exec echo "error S00000; remove_file $MYSQLTEST_VARDIR/tmp/test_nonexistent.tmp;" | $MYSQL_TEST 2>&1
# ----------------------------------------------------------------------------