Sisyphus repositório
Última atualização: 1 outubro 2023 | SRPMs: 18631 | Visitas: 37738430
en ru br
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


#! /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
 
 
 # ----------------------------------------------------------------------------
 
projeto & código: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
mantenedor atual: Michael Shigorin
mantenedor da tradução: Fernando Martini aka fmartini © 2009