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-26 06:21:48+01:00, tnurnberg@stripped +17 -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 thrown
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 specified in the
variable's definition.
client/mysqltest.c@stripped, 2007-11-26 06:21:46+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-26 06:21:46+01:00, tnurnberg@stripped +1 -0
ullstr() - the unsigned brother of llstr()
mysql-test/r/delayed.result@stripped, 2007-11-26 06:21:46+01:00, tnurnberg@stripped +16 -0
We throw a warning now when we adjust out of range parameters.
mysql-test/r/index_merge.result@stripped, 2007-11-26 06:21:46+01:00, tnurnberg@stripped +2 -0
We throw a warning now when we adjust out of range parameters.
mysql-test/r/innodb.result@stripped, 2007-11-26 06:21:46+01:00, tnurnberg@stripped +4 -0
We throw a warning now when we adjust out of range parameters.
mysql-test/r/innodb_mysql.result@stripped, 2007-11-26 06:21:46+01:00, tnurnberg@stripped +2 -0
We throw a warning now when we adjust out of range parameters.
mysql-test/r/packet.result@stripped, 2007-11-26 06:21:46+01:00, tnurnberg@stripped +8 -0
We throw a warning now when we adjust out of range parameters.
mysql-test/r/ps.result@stripped, 2007-11-26 06:21:46+01:00, tnurnberg@stripped +2 -0
We throw a warning now when we adjust out of range parameters.
mysql-test/r/subselect.result@stripped, 2007-11-26 06:21:46+01:00, tnurnberg@stripped +4 -0
We throw a warning now when we adjust out of range parameters.
mysql-test/r/type_bit.result@stripped, 2007-11-26 06:21:46+01:00, tnurnberg@stripped +2 -0
We throw a warning now when we adjust out of range parameters.
mysql-test/r/type_bit_innodb.result@stripped, 2007-11-26 06:21:46+01:00, tnurnberg@stripped +2 -0
We throw a warning now when we adjust out of range parameters.
mysql-test/r/variables.result@stripped, 2007-11-26 06:21:46+01:00, tnurnberg@stripped +25 -3
correct results: bounds and step apply to variables' default values, too
mysql-test/t/variables.test@stripped, 2007-11-26 06:21:46+01:00, tnurnberg@stripped +1 -1
correct results: bounds and step apply to variables' default values, too
mysys/my_getopt.c@stripped, 2007-11-26 06:21:46+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-26 06:21:46+01:00, tnurnberg@stripped +1 -1
minimum value for max-user-connections was higher than default
sql/set_var.cc@stripped, 2007-11-26 06:21:46+01:00, tnurnberg@stripped +63 -21
When the new value for a variable is out of bounds, we'll send the
client a warning (but not if the value was simply not a multiple of
'step'). sys_var_thd_ulong had this, sys_var_long_ptr_global didn't;
broken out and streamlined to avoid duplication of code.
strings/llstr.c@stripped, 2007-11-26 06:21:46+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-26 06:21:46 +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-26 06:21:46 +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/delayed.result b/mysql-test/r/delayed.result
--- a/mysql-test/r/delayed.result 2007-03-20 14:53:54 +01:00
+++ b/mysql-test/r/delayed.result 2007-11-26 06:21:46 +01:00
@@ -109,12 +109,20 @@ c1
DROP TABLE t1;
SET @@auto_increment_offset=
@bug20627_old_auto_increment_offset;
+Warnings:
+Warning 1292 Truncated incorrect auto_increment_offset value: '0->1'
SET @@auto_increment_increment=
@bug20627_old_auto_increment_increment;
+Warnings:
+Warning 1292 Truncated incorrect auto_increment_increment value: '0->1'
SET @@session.auto_increment_offset=
@bug20627_old_session_auto_increment_offset;
+Warnings:
+Warning 1292 Truncated incorrect auto_increment_offset value: '0->1'
SET @@session.auto_increment_increment=
@bug20627_old_session_auto_increment_increment;
+Warnings:
+Warning 1292 Truncated incorrect auto_increment_increment value: '0->1'
SET @bug20830_old_auto_increment_offset=
@@auto_increment_offset= 2;
SET @bug20830_old_auto_increment_increment=
@@ -237,12 +245,20 @@ SUM(c1)
DROP TABLE t1;
SET @@auto_increment_offset=
@bug20830_old_auto_increment_offset;
+Warnings:
+Warning 1292 Truncated incorrect auto_increment_offset value: '0->1'
SET @@auto_increment_increment=
@bug20830_old_auto_increment_increment;
+Warnings:
+Warning 1292 Truncated incorrect auto_increment_increment value: '0->1'
SET @@session.auto_increment_offset=
@bug20830_old_session_auto_increment_offset;
+Warnings:
+Warning 1292 Truncated incorrect auto_increment_offset value: '0->1'
SET @@session.auto_increment_increment=
@bug20830_old_session_auto_increment_increment;
+Warnings:
+Warning 1292 Truncated incorrect auto_increment_increment value: '0->1'
CREATE TABLE t1(a BIT);
INSERT DELAYED INTO t1 VALUES(1);
FLUSH TABLE t1;
diff -Nrup a/mysql-test/r/index_merge.result b/mysql-test/r/index_merge.result
--- a/mysql-test/r/index_merge.result 2007-07-14 20:02:07 +02:00
+++ b/mysql-test/r/index_merge.result 2007-11-26 06:21:46 +01:00
@@ -340,6 +340,8 @@ create table t4 (a int);
insert into t4 values (1),(4),(3);
set @save_join_buffer_size=@@join_buffer_size;
set join_buffer_size= 4000;
+Warnings:
+Warning 1292 Truncated incorrect join_buffer_size value: '4000->8228'
explain select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
from t0 as A force index(i1,i2), t0 as B force index (i1,i2)
where (A.key1 < 500000 or A.key2 < 3)
diff -Nrup a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
--- a/mysql-test/r/innodb.result 2007-07-18 14:22:00 +02:00
+++ b/mysql-test/r/innodb.result 2007-11-26 06:21:46 +01:00
@@ -1833,6 +1833,8 @@ show variables like "innodb_thread_concu
Variable_name Value
innodb_thread_concurrency 8
set global innodb_thread_concurrency=1001;
+Warnings:
+Warning 1292 Truncated incorrect innodb_thread_concurrency value: '1001->1000'
show variables like "innodb_thread_concurrency";
Variable_name Value
innodb_thread_concurrency 1000
@@ -1852,6 +1854,8 @@ show variables like "innodb_concurrency_
Variable_name Value
innodb_concurrency_tickets 1000
set global innodb_concurrency_tickets=0;
+Warnings:
+Warning 1292 Truncated incorrect innodb_concurrency_tickets value: '0->1'
show variables like "innodb_concurrency_tickets";
Variable_name Value
innodb_concurrency_tickets 1
diff -Nrup a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
--- a/mysql-test/r/innodb_mysql.result 2007-10-10 21:15:39 +02:00
+++ b/mysql-test/r/innodb_mysql.result 2007-11-26 06:21:46 +01:00
@@ -712,6 +712,8 @@ INSERT INTO t1(b,c) SELECT b,c FROM t2;
UPDATE t2 SET c='2007-01-03';
INSERT INTO t1(b,c) SELECT b,c FROM t2;
set @@sort_buffer_size=8192;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '8192->32804'
SELECT COUNT(*) FROM t1;
COUNT(*)
3072
diff -Nrup a/mysql-test/r/packet.result b/mysql-test/r/packet.result
--- a/mysql-test/r/packet.result 2004-07-21 18:27:42 +02:00
+++ b/mysql-test/r/packet.result 2007-11-26 06:21:46 +01:00
@@ -1,7 +1,15 @@
set global max_allowed_packet=100;
+Warnings:
+Warning 1292 Truncated incorrect max_allowed_packet value: '100->1024'
set max_allowed_packet=100;
+Warnings:
+Warning 1292 Truncated incorrect max_allowed_packet value: '100->1024'
set global net_buffer_length=100;
+Warnings:
+Warning 1292 Truncated incorrect net_buffer_length value: '100->1024'
set net_buffer_length=100;
+Warnings:
+Warning 1292 Truncated incorrect net_buffer_length value: '100->1024'
SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
len
1024
diff -Nrup a/mysql-test/r/ps.result b/mysql-test/r/ps.result
--- a/mysql-test/r/ps.result 2007-06-07 09:07:38 +02:00
+++ b/mysql-test/r/ps.result 2007-11-26 06:21:46 +01:00
@@ -806,6 +806,8 @@ select @@max_prepared_stmt_count;
@@max_prepared_stmt_count
0
set global max_prepared_stmt_count=10000000000000000;
+Warnings:
+Warning 1292 Truncated incorrect max_prepared_stmt_count value: '10000000000000000->1048576'
select @@max_prepared_stmt_count;
@@max_prepared_stmt_count
1048576
diff -Nrup a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
--- a/mysql-test/r/subselect.result 2007-06-29 09:39:15 +02:00
+++ b/mysql-test/r/subselect.result 2007-11-26 06:21:46 +01:00
@@ -3666,6 +3666,8 @@ CREATE TABLE t1 (a int, b int auto_incre
CREATE TABLE t2 (x int auto_increment, y int, z int,
PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
SET SESSION sort_buffer_size = 32 * 1024;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '32768->32804'
SELECT SQL_NO_CACHE COUNT(*)
FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
FROM t1) t;
@@ -4101,6 +4103,8 @@ INSERT INTO `t1` VALUES ('asdf','2007-02
INSERT INTO `t2` VALUES ('abcdefghijk');
INSERT INTO `t2` VALUES ('asdf');
SET session sort_buffer_size=8192;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '8192->32804'
SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2;
d1
1
diff -Nrup a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result
--- a/mysql-test/r/type_bit.result 2007-09-14 12:53:11 +02:00
+++ b/mysql-test/r/type_bit.result 2007-11-26 06:21:46 +01:00
@@ -269,6 +269,8 @@ a+0 b+0
56 379
68 454
set @@max_length_for_sort_data=0;
+Warnings:
+Warning 1292 Truncated incorrect max_length_for_sort_data value: '0->4'
select a+0, b+0 from t1 where a > 40 and a < 70 order by 2;
a+0 b+0
57 135
diff -Nrup a/mysql-test/r/type_bit_innodb.result b/mysql-test/r/type_bit_innodb.result
--- a/mysql-test/r/type_bit_innodb.result 2007-01-18 12:28:32 +01:00
+++ b/mysql-test/r/type_bit_innodb.result 2007-11-26 06:21:46 +01:00
@@ -269,6 +269,8 @@ a+0 b+0
56 379
68 454
set @@max_length_for_sort_data=0;
+Warnings:
+Warning 1292 Truncated incorrect max_length_for_sort_data value: '0->4'
select a+0, b+0 from t1 where a > 40 and a < 70 order by 2;
a+0 b+0
57 135
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-26 06:21:46 +01:00
@@ -214,12 +214,14 @@ net_read_timeout 600
net_retry_count 10
net_write_timeout 500
set net_buffer_length=1;
+Warnings:
+Warning 1292 Truncated incorrect net_buffer_length value: '1->1024'
show variables like 'net_buffer_length';
Variable_name Value
net_buffer_length 1024
set net_buffer_length=2000000000;
Warnings:
-Warning 1292 Truncated incorrect net_buffer_length value: '2000000000'
+Warning 1292 Truncated incorrect net_buffer_length value: '2000000000->1048576'
show variables like 'net_buffer_length';
Variable_name Value
net_buffer_length 1048576
@@ -238,7 +240,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 +265,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';
@@ -321,6 +323,8 @@ select @@autocommit, @@big_tables;
@@autocommit @@big_tables
1 1
set global binlog_cache_size=100;
+Warnings:
+Warning 1292 Truncated incorrect binlog_cache_size value: '100->4096'
set bulk_insert_buffer_size=100;
set character set cp1251_koi8;
set character set default;
@@ -349,13 +353,21 @@ set global flush_time=100;
set insert_id=1;
set interactive_timeout=100;
set join_buffer_size=100;
+Warnings:
+Warning 1292 Truncated incorrect join_buffer_size value: '100->8228'
set last_insert_id=1;
set global local_infile=1;
set long_query_time=100;
set low_priority_updates=1;
set max_allowed_packet=100;
+Warnings:
+Warning 1292 Truncated incorrect max_allowed_packet value: '100->1024'
set global max_binlog_cache_size=100;
+Warnings:
+Warning 1292 Truncated incorrect max_binlog_cache_size value: '100->4096'
set global max_binlog_size=100;
+Warnings:
+Warning 1292 Truncated incorrect max_binlog_size value: '100->4096'
set global max_connect_errors=100;
set global max_connections=100;
set global max_delayed_threads=100;
@@ -370,17 +382,25 @@ select @@max_user_connections;
set global max_write_lock_count=100;
set myisam_sort_buffer_size=100;
set net_buffer_length=100;
+Warnings:
+Warning 1292 Truncated incorrect net_buffer_length value: '100->1024'
set net_read_timeout=100;
set net_write_timeout=100;
set global query_cache_limit=100;
set global query_cache_size=100;
set global query_cache_type=demand;
set read_buffer_size=100;
+Warnings:
+Warning 1292 Truncated incorrect read_buffer_size value: '100->8228'
set read_rnd_buffer_size=100;
+Warnings:
+Warning 1292 Truncated incorrect read_rnd_buffer_size value: '100->8228'
set global rpl_recovery_rank=100;
set global server_id=100;
set global slow_launch_time=100;
set sort_buffer_size=100;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '100->32804'
set @@max_sp_recursion_depth=10;
select @@max_sp_recursion_depth;
@@max_sp_recursion_depth
@@ -570,6 +590,8 @@ SHOW VARIABLES LIKE 'MYISAM_DATA_POINTER
Variable_name Value
myisam_data_pointer_size 7
SET GLOBAL table_cache=-1;
+Warnings:
+Warning 1292 Truncated incorrect table_cache value: '0->1'
SHOW VARIABLES LIKE 'table_cache';
Variable_name Value
table_cache 1
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-26 06:21:46 +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-26 06:21:46 +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 */
}
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-26 06:21:46 +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/sql/set_var.cc b/sql/set_var.cc
--- a/sql/set_var.cc 2007-10-29 08:25:38 +01:00
+++ b/sql/set_var.cc 2007-11-26 06:21:46 +01:00
@@ -113,6 +113,11 @@ static int check_max_delayed_threads(THD
static void fix_thd_mem_root(THD *thd, enum_var_type type);
static void fix_trans_mem_root(THD *thd, enum_var_type type);
static void fix_server_id(THD *thd, enum_var_type type);
+static ulonglong fix_unsigned(ulonglong in,
+ const struct my_option *option_limits,
+ ulonglong *chk);
+static void throw_bounds_warning(THD *thd, const char *name,
+ ulonglong from, ulonglong to);
static KEY_CACHE *create_key_cache(const char *name, uint length);
void fix_sql_mode_var(THD *thd, enum_var_type type);
static byte *get_error_count(THD *thd);
@@ -1448,6 +1453,44 @@ static void fix_server_id(THD *thd, enum
}
+static ulonglong fix_unsigned(ulonglong in,
+ const struct my_option *option_limits,
+ ulonglong *chk)
+{
+ ulonglong out= getopt_ull_limit_value(in, option_limits);
+ /*
+ If we've already truncated or there is no step,
+ the check is immaterial.
+ */
+ if (chk && (option_limits->block_size > 1) && (*chk == in))
+ {
+ struct my_option tmp_limits;
+ memcpy(&tmp_limits, option_limits, sizeof(struct my_option));
+ tmp_limits.block_size= 1;
+ if (getopt_ull_limit_value(in, &tmp_limits) == in)
+ *chk= out;
+ }
+ return out;
+}
+
+static void throw_bounds_warning(THD *thd, const char *name,
+ ulonglong from, ulonglong to)
+{
+ if (from != to)
+ {
+ char buf[44], *p;
+ ullstr(from, buf);
+ p= strchr(buf, '\0');
+ strcat(p, "->");
+ ullstr(to, p+2);
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE), name,
+ buf);
+ }
+}
+
+
sys_var_long_ptr::
sys_var_long_ptr(const char *name_arg, ulong *value_ptr_arg,
sys_after_update_func after_update_arg)
@@ -1468,9 +1511,20 @@ bool sys_var_long_ptr_global::update(THD
ulonglong tmp= var->save_result.ulonglong_value;
pthread_mutex_lock(guard);
if (option_limits)
- *value= (ulong) getopt_ull_limit_value(tmp, option_limits);
+ *value= (ulong) fix_unsigned(tmp, option_limits,
+ &var->save_result.ulonglong_value);
else
+ {
+#if SIZEOF_LONG < SIZEOF_LONG_LONG
+ /* Avoid overflows on 32 bit systems */
+ if (tmp > (ulonglong) ~(ulong) 0)
+ tmp= ((ulonglong) ~(ulong) 0);
+#endif
*value= (ulong) tmp;
+ }
+
+ throw_bounds_warning(thd, name, var->save_result.ulonglong_value, *value);
+
pthread_mutex_unlock(guard);
return 0;
}
@@ -1539,38 +1593,26 @@ bool sys_var_thd_ulong::check(THD *thd,
bool sys_var_thd_ulong::update(THD *thd, set_var *var)
{
ulonglong tmp= var->save_result.ulonglong_value;
- char buf[22];
- bool truncated= false;
/* Don't use bigger value than given with --maximum-variable-name=.. */
if ((ulong) tmp > max_system_variables.*offset)
- {
- truncated= true;
- llstr(tmp, buf);
tmp= max_system_variables.*offset;
- }
-#if SIZEOF_LONG == 4
- /* Avoid overflows on 32 bit systems */
- if (tmp > (ulonglong) ~(ulong) 0)
- {
- truncated= true;
- llstr(tmp, buf);
+ if (option_limits)
+ tmp= (ulong) fix_unsigned(tmp, option_limits,
+ &var->save_result.ulonglong_value);
+#if SIZEOF_LONG < SIZEOF_LONG_LONG
+ else if (tmp > (ulonglong) ~(ulong) 0)
tmp= ((ulonglong) ~(ulong) 0);
- }
#endif
- if (truncated)
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_TRUNCATED_WRONG_VALUE,
- ER(ER_TRUNCATED_WRONG_VALUE), name,
- buf);
- if (option_limits)
- tmp= (ulong) getopt_ull_limit_value(tmp, option_limits);
if (var->type == OPT_GLOBAL)
global_system_variables.*offset= (ulong) tmp;
else
thd->variables.*offset= (ulong) tmp;
+
+ throw_bounds_warning(thd, name, var->save_result.ulonglong_value, tmp);
+
return 0;
}
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-26 06:21:46 +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;
+}