List:Commits« Previous MessageNext Message »
From:Tatjana A Nuernberg Date:November 25 2007 7:05pm
Subject:bk commit into 5.0 tree (tnurnberg:1.2557) BUG#31177
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of tnurnberg. When tnurnberg does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-11-25 19:05:07+01:00, tnurnberg@stripped +7 -0
  Bug#31177: Server variables can't be set to their current values
  
  Default values of variables were not subject to upper/lower bounds
  and step, while setting variables was. Bounds and step are also
  applied to defaults now; defaults are corrected quietly, values
  given by the user are corrected, and a correction-warning is printed
  to the log as needed. Lastly, very large values could wrap around,
  starting from 0 again. They are bounded at the maximum value for the
  respective data-type now if no lower maximum is specific in the
  variable's definition.

  client/mysqltest.c@stripped, 2007-11-25 19:05:05+01:00, tnurnberg@stripped +1 -1
    adjust minimum for "sleep" option so default value is no longer
    out of bounds.

  include/m_string.h@stripped, 2007-11-25 19:05:05+01:00, tnurnberg@stripped +1 -0
    ullstr() - the unsigned brother of llstr()

  mysql-test/r/variables.result@stripped, 2007-11-25 19:05:05+01:00, tnurnberg@stripped +2 -2
    correct results: bounds and step apply to variables' default values, too

  mysql-test/t/variables.test@stripped, 2007-11-25 19:05:05+01:00, tnurnberg@stripped +1 -1
    correct results: bounds and step apply to variables' default values, too

  mysys/my_getopt.c@stripped, 2007-11-25 19:05:05+01:00, tnurnberg@stripped +127 -34
    - apply bounds/step to default values of variables (based on work by serg)
    - print complaints about incorrect values for variables (truncation etc.,
      by requestion of consulting)
    - if no lower maximum is specified in variable definition, bound unsigned
      values at their maximum to prevent wrap-around

  sql/mysqld.cc@stripped, 2007-11-25 19:05:06+01:00, tnurnberg@stripped +1 -1
    minimum value for max-user-connections was higher than default

  strings/llstr.c@stripped, 2007-11-25 19:05:06+01:00, tnurnberg@stripped +6 -0
    ullstr() - the unsigned brother of llstr()

diff -Nrup a/client/mysqltest.c b/client/mysqltest.c
--- a/client/mysqltest.c	2007-10-05 18:18:47 +02:00
+++ b/client/mysqltest.c	2007-11-25 19:05:05 +01:00
@@ -4986,7 +4986,7 @@ static struct my_option my_long_options[
    "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG,
    0, 0, 0, 0, 0, 0},
   {"sleep", 'T', "Sleep always this many seconds on sleep commands.",
-   (gptr*) &opt_sleep, (gptr*) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, 0, 0,
+   (gptr*) &opt_sleep, (gptr*) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, -1, 0,
    0, 0, 0},
   {"socket", 'S', "Socket file to use for connection.",
    (gptr*) &unix_sock, (gptr*) &unix_sock, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
diff -Nrup a/include/m_string.h b/include/m_string.h
--- a/include/m_string.h	2007-05-30 20:47:50 +02:00
+++ b/include/m_string.h	2007-11-25 19:05:05 +01:00
@@ -219,6 +219,7 @@ double my_strtod(const char *str, char *
 double my_atof(const char *nptr);
 
 extern char *llstr(longlong value,char *buff);
+extern char *ullstr(longlong value,char *buff);
 #ifndef HAVE_STRTOUL
 extern long strtol(const char *str, char **ptr, int base);
 extern ulong strtoul(const char *str, char **ptr, int base);
diff -Nrup a/mysql-test/r/variables.result b/mysql-test/r/variables.result
--- a/mysql-test/r/variables.result	2007-10-29 08:25:37 +01:00
+++ b/mysql-test/r/variables.result	2007-11-25 19:05:05 +01:00
@@ -238,7 +238,7 @@ show variables like '%alloc%';
 Variable_name	Value
 query_alloc_block_size	8192
 query_prealloc_size	8192
-range_alloc_block_size	2048
+range_alloc_block_size	4096
 transaction_alloc_block_size	8192
 transaction_prealloc_size	4096
 set @@range_alloc_block_size=1024*16;
@@ -263,7 +263,7 @@ show variables like '%alloc%';
 Variable_name	Value
 query_alloc_block_size	8192
 query_prealloc_size	8192
-range_alloc_block_size	2048
+range_alloc_block_size	4096
 transaction_alloc_block_size	8192
 transaction_prealloc_size	4096
 SELECT @@version LIKE 'non-existent';
diff -Nrup a/mysql-test/t/variables.test b/mysql-test/t/variables.test
--- a/mysql-test/t/variables.test	2007-10-29 08:25:37 +01:00
+++ b/mysql-test/t/variables.test	2007-11-25 19:05:05 +01:00
@@ -126,7 +126,7 @@ set GLOBAL query_cache_size=100000;
 set GLOBAL myisam_max_sort_file_size=2000000;
 show global variables like 'myisam_max_sort_file_size';
 set GLOBAL myisam_max_sort_file_size=default;
---replace_result 2147483647 FILE_SIZE 9223372036854775807 FILE_SIZE
+--replace_result 2147482624 FILE_SIZE 2146435072 FILE_SIZE
 show variables like 'myisam_max_sort_file_size';
 
 set global net_retry_count=10, session net_retry_count=10;
diff -Nrup a/mysys/my_getopt.c b/mysys/my_getopt.c
--- a/mysys/my_getopt.c	2007-10-04 10:33:56 +02:00
+++ b/mysys/my_getopt.c	2007-11-25 19:05:05 +01:00
@@ -22,6 +22,7 @@
 #include <errno.h>
 
 static void default_reporter(enum loglevel level, const char *format, ...);
+static void null_reporter(enum loglevel level, const char *format, ...);
 my_error_reporter my_getopt_error_reporter= &default_reporter;
 
 static int findopt(char *optpat, uint length,
@@ -31,6 +32,7 @@ my_bool getopt_compare_strings(const cha
 			       const char *t,
 			       uint length);
 static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
+static longlong getopt_ll_limit_value(longlong, const struct my_option *);
 static ulonglong getopt_ull(char *arg, const struct my_option *optp,
 			    int *err);
 static void init_variables(const struct my_option *options);
@@ -59,6 +61,13 @@ char *disabled_my_option= (char*) "0";
 
 my_bool my_getopt_print_errors= 1;
 
+/* 
+   This is a flag that can be set in client programs. 1 means that
+   my_getopt will skip over options it does not know how to handle.
+*/
+
+my_bool my_getopt_skip_unknown= 0;
+
 static void default_reporter(enum loglevel level,
                              const char *format, ...)
 {
@@ -73,6 +82,11 @@ static void default_reporter(enum loglev
   fflush(stderr);
 }
 
+static void null_reporter(enum loglevel level,
+                          const char *format, ...)
+{
+}
+
 /* 
   function: handle_options
 
@@ -105,12 +119,17 @@ int handle_options(int *argc, char ***ar
   int error;
 
   LINT_INIT(opt_found);
+
+  /* handle_options() assumes arg0 (program name) always exists */
+  DBUG_ASSERT(argc && *argc >= 1);
+  DBUG_ASSERT(argv && *argv);
   (*argc)--; /* Skip the program name */
   (*argv)++; /*      --- || ----      */
   init_variables(longopts);
 
   for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
   {
+    char **first= pos;
     char *cur_arg= *pos;
     if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
     {
@@ -217,12 +236,11 @@ int handle_options(int *argc, char ***ar
 		/*
 		  We were called with a special prefix, we can reuse opt_found
 		*/
-		opt_str+= (special_opt_prefix_lengths[i] + 1);
+		opt_str+= special_opt_prefix_lengths[i] + 1;
+                length-= special_opt_prefix_lengths[i] + 1;
 		if (i == OPT_LOOSE)
 		  option_is_loose= 1;
-		if ((opt_found= findopt(opt_str, length -
-					(special_opt_prefix_lengths[i] + 1),
-					&optp, &prev_found)))
+		if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
 		{
 		  if (opt_found > 1)
 		  {
@@ -255,11 +273,25 @@ int handle_options(int *argc, char ***ar
 		  }
 		  break; /* break from the inner loop, main loop continues */
 		}
+                i= -1; /* restart the loop */
 	      }
 	    }
 	  }
 	  if (!opt_found)
 	  {
+            if (my_getopt_skip_unknown)
+            {
+              /*
+                preserve all the components of this unknown option, this may
+                occurr when the user provides options like: "-O foo" or
+                "--set-variable foo" (note that theres a space in there)
+                Generally, these kind of options are to be avoided
+              */
+              do {
+                (*argv)[argvpos++]= *first++;
+              } while (first <= pos);
+              continue;
+            }
 	    if (must_be_var)
 	    {
 	      if (my_getopt_print_errors)
@@ -492,7 +524,7 @@ invalid value '%s'\n",
       }
       get_one_option(optp->id, optp, argument);
 
-      (*argc)--; /* option handled (short or long), decrease argument count */
+      (*argc)--; /* option handled (short or long), decrease argument count */
     }
     else /* non-option found */
       (*argv)[argvpos++]= cur_arg;
@@ -575,13 +607,17 @@ static int setval(const struct my_option
       *((my_bool*) result_pos)= (my_bool) atoi(argument) != 0;
       break;
     case GET_INT:
-    case GET_UINT:           /* fall through */
       *((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
       break;
+    case GET_UINT:
+      *((uint*) result_pos)= (uint) getopt_ull(argument, opts, &err);
+      break;
     case GET_LONG:
-    case GET_ULONG:          /* fall through */
       *((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
       break;
+    case GET_ULONG:
+      *((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
+      break;
     case GET_LL:
       *((longlong*) result_pos)= getopt_ll(argument, opts, &err);
       break;
@@ -733,23 +769,40 @@ static longlong eval_num_suffix (char *a
 
 static longlong getopt_ll(char *arg, const struct my_option *optp, int *err)
 {
-  longlong num;
+  longlong num=eval_num_suffix(arg, err, (char*) optp->name);
+  return getopt_ll_limit_value(num, optp);
+}
+
+/*
+  function: getopt_ll_limit_value
+
+  Applies min/max/block_size to a numeric value of an option.
+  Returns "fixed" value.
+*/
+
+static longlong getopt_ll_limit_value(longlong num,
+                                      const struct my_option *optp)
+{
+  longlong old= num;
+  char buf1[255] __attribute__((unused)), buf2[255] __attribute__((unused));
   ulonglong block_size= (optp->block_size ? (ulonglong) optp->block_size : 1L);
-  
-  num= eval_num_suffix(arg, err, (char*) optp->name);
+
   if (num > 0 && (ulonglong) num > (ulonglong) optp->max_value &&
       optp->max_value) /* if max value is not set -> no upper limit */
-  {
-    char buf[22];
-    my_getopt_error_reporter(WARNING_LEVEL,
-                             "Truncated incorrect %s value: '%s'", 
-                             optp->name, llstr(num, buf));
-    
     num= (ulonglong) optp->max_value;
-  }
+
   num= ((num - optp->sub_size) / block_size);
   num= (longlong) (num * block_size);
-  return max(num, optp->min_value);
+
+  num= max(num, optp->min_value);
+
+  if (num != old)
+    my_getopt_error_reporter(WARNING_LEVEL,
+                             "option '%s' (type %d): "
+                             "signed value '%s' adjusted to '%s'",
+                             optp->name, optp->var_type & GET_TYPE_MASK,
+                             llstr(old, buf1), llstr(num, buf2));
+  return num;
 }
 
 /*
@@ -761,18 +814,33 @@ static longlong getopt_ll(char *arg, con
 
 static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err)
 {
-  ulonglong num;
-
-  num= eval_num_suffix(arg, err, (char*) optp->name);  
+  ulonglong num= eval_num_suffix(arg, err, (char*) optp->name);
   return getopt_ull_limit_value(num, optp);
 }
 
 
 ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp)
 {
+  ulonglong old= num;
+  char buf1[255] __attribute__((unused)), buf2[255] __attribute__((unused));
+
   if ((ulonglong) num > (ulonglong) optp->max_value &&
       optp->max_value) /* if max value is not set -> no upper limit */
     num= (ulonglong) optp->max_value;
+
+  switch ((optp->var_type & GET_TYPE_MASK)) {
+  case GET_UINT:
+    if (num > (ulonglong) ~(uint) 0)
+      num= ((ulonglong) ~(uint) 0);
+    break;
+#if SIZEOF_LONG < SIZEOF_LONG_LONG
+  case GET_ULONG:
+    if (num > (ulonglong) ~(ulong) 0)
+      num= ((ulonglong) ~(ulong) 0);
+    break;
+#endif
+  }
+
   if (optp->block_size > 1)
   {
     num/= (ulonglong) optp->block_size;
@@ -780,6 +848,13 @@ ulonglong getopt_ull_limit_value(ulonglo
   }
   if (num < (ulonglong) optp->min_value)
     num= (ulonglong) optp->min_value;
+
+  if (num != old)
+    my_getopt_error_reporter(WARNING_LEVEL,
+                             "option '%s' (type %d): "
+                             "unsigned value '%s' adjusted to '%s'",
+                             optp->name, optp->var_type & GET_TYPE_MASK,
+                             ullstr(old, buf1), ullstr(num, buf2));
   return num;
 }
 
@@ -789,38 +864,53 @@ ulonglong getopt_ull_limit_value(ulonglo
 
   SYNOPSIS
     init_one_value()
-    option		Option to initialize
-    value		Pointer to variable
+    optp               Option to initialize
+    value              Pointer to variable
 */
 
-static void init_one_value(const struct my_option *option, gptr *variable,
+static void init_one_value(const struct my_option *optp, gptr *variable,
 			   longlong value)
 {
-  switch ((option->var_type & GET_TYPE_MASK)) {
+  /*
+    Gag reporter (which isn't default_reporter when we're mysqld)
+    while setting defaults - we'll apply step-size and bounds even
+    to defaults, but silently.
+  */
+  my_error_reporter save_reporter= my_getopt_error_reporter;
+
+  DBUG_ENTER("init_one_value");
+
+  my_getopt_error_reporter= null_reporter;
+
+  switch ((optp->var_type & GET_TYPE_MASK)) {
   case GET_BOOL:
     *((my_bool*) variable)= (my_bool) value;
     break;
   case GET_INT:
-    *((int*) variable)= (int) value;
+    *((int*) variable)= (int) getopt_ll_limit_value(value, optp);
     break;
   case GET_UINT:
-    *((uint*) variable)= (uint) value;
+    *((uint*) variable)= (uint) getopt_ull_limit_value(value, optp);
     break;
   case GET_LONG:
-    *((long*) variable)= (long) value;
+    *((long*) variable)= (long) getopt_ll_limit_value(value, optp);
     break;
   case GET_ULONG:
-    *((ulong*) variable)= (ulong) value;
+    *((ulong*) variable)= (ulong) getopt_ull_limit_value(value, optp);
     break;
   case GET_LL:
-    *((longlong*) variable)= (longlong) value;
+    *((longlong*) variable)= (longlong) getopt_ll_limit_value(value, optp);
     break;
   case GET_ULL:
-    *((ulonglong*) variable)=  (ulonglong) value;
+    *((ulonglong*) variable)=  (ulonglong) getopt_ull_limit_value(value, optp);
     break;
   default: /* dummy default to avoid compiler warnings */
     break;
   }
+
+  my_getopt_error_reporter= save_reporter;
+
+  DBUG_VOID_RETURN;
 }
 
 
@@ -839,9 +929,11 @@ static void init_one_value(const struct 
 
 static void init_variables(const struct my_option *options)
 {
+  DBUG_ENTER("init_variables");
   for (; options->name; options++)
   {
     gptr *variable;
+    DBUG_PRINT("options", ("name: '%s'", options->name));
     /*
       We must set u_max_value first as for some variables
       options->u_max_value == options->value and in this case we want to
@@ -855,6 +947,7 @@ static void init_variables(const struct 
 	(variable= (*getopt_get_addr)("", 0, options)))
       init_one_value(options, variable, options->def_value);
   }
+  DBUG_VOID_RETURN;
 }
 
 
@@ -957,8 +1050,8 @@ void my_print_variables(const struct my_
 		  (*getopt_get_addr)("", 0, optp) : optp->value);
     if (value)
     {
-      printf("%s", optp->name);
-      length= (uint) strlen(optp->name);
+      printf("%s ", optp->name);
+      length= (uint) strlen(optp->name)+1;
       for (; length < name_space; length++)
 	putchar(' ');
       switch ((optp->var_type & GET_TYPE_MASK)) {
@@ -977,7 +1070,7 @@ void my_print_variables(const struct my_
 	printf("%d\n", *((uint*) value));
 	break;
       case GET_LONG:
-	printf("%lu\n", *((long*) value));
+	printf("%ld\n", *((long*) value));
 	break;
       case GET_ULONG:
 	printf("%lu\n", *((ulong*) value));
diff -Nrup a/sql/mysqld.cc b/sql/mysqld.cc
--- a/sql/mysqld.cc	2007-10-29 09:52:39 +01:00
+++ b/sql/mysqld.cc	2007-11-25 19:05:06 +01:00
@@ -5982,7 +5982,7 @@ The minimum value for this variable is 4
   {"max_user_connections", OPT_MAX_USER_CONNECTIONS,
    "The maximum number of active connections for a single user (0 = no limit).",
    (gptr*) &max_user_connections, (gptr*) &max_user_connections, 0, GET_UINT,
-   REQUIRED_ARG, 0, 1, ~0, 0, 1, 0},
+   REQUIRED_ARG, 0, 0, ~0, 0, 1, 0},
   {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
    "After this many write locks, allow some read locks to run in between.",
    (gptr*) &max_write_lock_count, (gptr*) &max_write_lock_count, 0, GET_ULONG,
diff -Nrup a/strings/llstr.c b/strings/llstr.c
--- a/strings/llstr.c	2006-12-23 20:04:30 +01:00
+++ b/strings/llstr.c	2007-11-25 19:05:06 +01:00
@@ -32,3 +32,9 @@ char *llstr(longlong value,char *buff)
   longlong10_to_str(value,buff,-10);
   return buff;
 }
+
+char *ullstr(longlong value,char *buff)
+{
+  longlong10_to_str(value,buff,10);
+  return buff;
+}
Thread
bk commit into 5.0 tree (tnurnberg:1.2557) BUG#31177Tatjana A Nuernberg25 Nov