mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Bug#55873 short startup options do not work in 5.5
Before this fix, the server did not recognize 'short' (as in -a) options but only 'long' (as in --ansi) options in the startup command line, due to earlier changes in 5.5 introduced for the performance schema. The root cause is that handle_options() did not honor the my_getopt_skip_unknown flag when parsing 'short' options. The fix changes handle_options(), so that my_getopt_skip_unknown is honored in all cases. Note that there are limitations to this, see the added doxygen documentation in handle_options(). The current usage of handle_options() by the server to parse early performance schema options fits within the limitations. This has been enforced by an assert for PARSE_EARLY options, for safety.
This commit is contained in:
2
mysql-test/suite/perfschema/r/bad_option_3.result
Normal file
2
mysql-test/suite/perfschema/r/bad_option_3.result
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Found: unknown option '-x'
|
||||||
|
Found: Aborting
|
2
mysql-test/suite/perfschema/r/bad_option_4.result
Normal file
2
mysql-test/suite/perfschema/r/bad_option_4.result
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Found: Can't change dir to.*bad_option_h_param
|
||||||
|
Found: Aborting
|
2
mysql-test/suite/perfschema/r/bad_option_5.result
Normal file
2
mysql-test/suite/perfschema/r/bad_option_5.result
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Found: unknown option '-X'
|
||||||
|
Found: Aborting
|
27
mysql-test/suite/perfschema/r/short_option_1.result
Normal file
27
mysql-test/suite/perfschema/r/short_option_1.result
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
select 'Ok, the server started' as result;
|
||||||
|
result
|
||||||
|
Ok, the server started
|
||||||
|
select @@SQL_MODE;
|
||||||
|
@@SQL_MODE
|
||||||
|
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI
|
||||||
|
show variables like 'sql_mode';
|
||||||
|
Variable_name Value
|
||||||
|
sql_mode REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI
|
||||||
|
select @@character_set_server;
|
||||||
|
@@character_set_server
|
||||||
|
utf8
|
||||||
|
show variables like 'character_set_system';
|
||||||
|
Variable_name Value
|
||||||
|
character_set_system utf8
|
||||||
|
show variables like 'log';
|
||||||
|
Variable_name Value
|
||||||
|
log ON
|
||||||
|
show variables like 'general_log';
|
||||||
|
Variable_name Value
|
||||||
|
general_log ON
|
||||||
|
show variables like 'new';
|
||||||
|
Variable_name Value
|
||||||
|
new ON
|
||||||
|
show variables like 'log_warnings';
|
||||||
|
Variable_name Value
|
||||||
|
log_warnings 3
|
9
mysql-test/suite/perfschema/r/short_option_2.result
Normal file
9
mysql-test/suite/perfschema/r/short_option_2.result
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
select 'Ok, the server started' as result;
|
||||||
|
result
|
||||||
|
Ok, the server started
|
||||||
|
select @@SQL_MODE;
|
||||||
|
@@SQL_MODE
|
||||||
|
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI
|
||||||
|
select @@log_warnings;
|
||||||
|
@@log_warnings
|
||||||
|
5
|
49
mysql-test/suite/perfschema/t/bad_option_3.test
Normal file
49
mysql-test/suite/perfschema/t/bad_option_3.test
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; version 2 of the License.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
|
||||||
|
|
||||||
|
# Tests for PERFORMANCE_SCHEMA
|
||||||
|
# Check error handling for invalid server start options
|
||||||
|
|
||||||
|
--source include/not_embedded.inc
|
||||||
|
--source include/have_perfschema.inc
|
||||||
|
|
||||||
|
let $outfile= $MYSQLTEST_VARDIR/tmp/bad_option_3.txt;
|
||||||
|
--error 0,1
|
||||||
|
--remove_file $outfile
|
||||||
|
--error 2
|
||||||
|
--exec $MYSQLD_BOOTSTRAP_CMD --loose-console -a -x > $outfile 2>&1
|
||||||
|
|
||||||
|
perl;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/bad_option_3.txt";
|
||||||
|
open(FILE, "<", $fname) or die;
|
||||||
|
my @lines= <FILE>;
|
||||||
|
# those must be in the file for the test to pass
|
||||||
|
my @patterns=
|
||||||
|
("unknown option '-x'",
|
||||||
|
"Aborting");
|
||||||
|
foreach my $one_line (@lines)
|
||||||
|
{
|
||||||
|
foreach my $one_pattern (@patterns)
|
||||||
|
{
|
||||||
|
# print pattern, not line, to get a stable output
|
||||||
|
print "Found: $one_pattern\n" if ($one_line =~ /$one_pattern/);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close FILE;
|
||||||
|
EOF
|
||||||
|
--remove_file $outfile
|
||||||
|
|
49
mysql-test/suite/perfschema/t/bad_option_4.test
Normal file
49
mysql-test/suite/perfschema/t/bad_option_4.test
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; version 2 of the License.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
|
||||||
|
|
||||||
|
# Tests for PERFORMANCE_SCHEMA
|
||||||
|
# Check error handling for invalid server start options
|
||||||
|
|
||||||
|
--source include/not_embedded.inc
|
||||||
|
--source include/have_perfschema.inc
|
||||||
|
|
||||||
|
let $outfile= $MYSQLTEST_VARDIR/tmp/bad_option_4.txt;
|
||||||
|
--error 0,1
|
||||||
|
--remove_file $outfile
|
||||||
|
--error 1
|
||||||
|
--exec $MYSQLD_BOOTSTRAP_CMD --loose-console -a -h bad_option_h_param > $outfile 2>&1
|
||||||
|
|
||||||
|
perl;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/bad_option_4.txt";
|
||||||
|
open(FILE, "<", $fname) or die;
|
||||||
|
my @lines= <FILE>;
|
||||||
|
# those must be in the file for the test to pass
|
||||||
|
my @patterns=
|
||||||
|
("Can't change dir to.*bad_option_h_param",
|
||||||
|
"Aborting");
|
||||||
|
foreach my $one_line (@lines)
|
||||||
|
{
|
||||||
|
foreach my $one_pattern (@patterns)
|
||||||
|
{
|
||||||
|
# print pattern, not line, to get a stable output
|
||||||
|
print "Found: $one_pattern\n" if ($one_line =~ /$one_pattern/);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close FILE;
|
||||||
|
EOF
|
||||||
|
--remove_file $outfile
|
||||||
|
|
52
mysql-test/suite/perfschema/t/bad_option_5.test
Normal file
52
mysql-test/suite/perfschema/t/bad_option_5.test
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; version 2 of the License.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
|
||||||
|
|
||||||
|
# Tests for PERFORMANCE_SCHEMA
|
||||||
|
# Check error handling for invalid server start options
|
||||||
|
|
||||||
|
--source include/not_embedded.inc
|
||||||
|
--source include/have_perfschema.inc
|
||||||
|
|
||||||
|
let $outfile= $MYSQLTEST_VARDIR/tmp/bad_option_5.txt;
|
||||||
|
--error 0,1
|
||||||
|
--remove_file $outfile
|
||||||
|
--error 2
|
||||||
|
--exec $MYSQLD_BOOTSTRAP_CMD --loose-console -aXbroken > $outfile 2>&1
|
||||||
|
|
||||||
|
# -aXbroken should be parsed as -a -Xbroken, or --ansi -Xbroken,
|
||||||
|
# therefore the -X option is what the server should complain about
|
||||||
|
|
||||||
|
perl;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/bad_option_5.txt";
|
||||||
|
open(FILE, "<", $fname) or die;
|
||||||
|
my @lines= <FILE>;
|
||||||
|
# those must be in the file for the test to pass
|
||||||
|
my @patterns=
|
||||||
|
("unknown option '-X'",
|
||||||
|
"Aborting");
|
||||||
|
foreach my $one_line (@lines)
|
||||||
|
{
|
||||||
|
foreach my $one_pattern (@patterns)
|
||||||
|
{
|
||||||
|
# print pattern, not line, to get a stable output
|
||||||
|
print "Found: $one_pattern\n" if ($one_line =~ /$one_pattern/);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close FILE;
|
||||||
|
EOF
|
||||||
|
--remove_file $outfile
|
||||||
|
|
1
mysql-test/suite/perfschema/t/short_option_1-master.opt
Normal file
1
mysql-test/suite/perfschema/t/short_option_1-master.opt
Normal file
@ -0,0 +1 @@
|
|||||||
|
-a -n -Cutf8 --collation=utf8_bin -l -T12 -W3
|
35
mysql-test/suite/perfschema/t/short_option_1.test
Normal file
35
mysql-test/suite/perfschema/t/short_option_1.test
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; version 2 of the License.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
|
||||||
|
|
||||||
|
# Tests for PERFORMANCE_SCHEMA
|
||||||
|
# Check server start for short server start options
|
||||||
|
|
||||||
|
select 'Ok, the server started' as result;
|
||||||
|
|
||||||
|
# See the associated -master.opt file.
|
||||||
|
|
||||||
|
select @@SQL_MODE;
|
||||||
|
show variables like 'sql_mode';
|
||||||
|
|
||||||
|
select @@character_set_server;
|
||||||
|
show variables like 'character_set_system';
|
||||||
|
|
||||||
|
show variables like 'log';
|
||||||
|
show variables like 'general_log';
|
||||||
|
|
||||||
|
show variables like 'new';
|
||||||
|
|
||||||
|
show variables like 'log_warnings';
|
||||||
|
|
1
mysql-test/suite/perfschema/t/short_option_2-master.opt
Normal file
1
mysql-test/suite/perfschema/t/short_option_2-master.opt
Normal file
@ -0,0 +1 @@
|
|||||||
|
-aW5
|
29
mysql-test/suite/perfschema/t/short_option_2.test
Normal file
29
mysql-test/suite/perfschema/t/short_option_2.test
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; version 2 of the License.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
|
||||||
|
|
||||||
|
# Tests for PERFORMANCE_SCHEMA
|
||||||
|
# Check server start for short server start options
|
||||||
|
|
||||||
|
select 'Ok, the server started' as result;
|
||||||
|
|
||||||
|
# See the associated -master.opt file.
|
||||||
|
# -aW5 should be parsed as -a -W5, which are two separate short options
|
||||||
|
# stuffed inside a single argv[i] argument.
|
||||||
|
|
||||||
|
# Should contain ANSI, since we started the server with -a (stands for --ansi)
|
||||||
|
select @@SQL_MODE;
|
||||||
|
|
||||||
|
# Should be 5, since we started the server with -W5
|
||||||
|
select @@log_warnings;
|
@ -98,6 +98,49 @@ void my_getopt_register_get_addr(my_getopt_value func_addr)
|
|||||||
matches with one of the options in struct 'my_option'.
|
matches with one of the options in struct 'my_option'.
|
||||||
Check that option was given an argument if it requires one
|
Check that option was given an argument if it requires one
|
||||||
Call the optional 'get_one_option()' function once for each option.
|
Call the optional 'get_one_option()' function once for each option.
|
||||||
|
|
||||||
|
Note that handle_options() can be invoked multiple times to
|
||||||
|
parse a command line in several steps.
|
||||||
|
In this case, use the global flag @c my_getopt_skip_unknown to indicate
|
||||||
|
that options unknown in the current step should be preserved in the
|
||||||
|
command line for later parsing in subsequent steps.
|
||||||
|
|
||||||
|
For 'long' options (--a_long_option), @c my_getopt_skip_unknown is
|
||||||
|
fully supported. Command line parameters such as:
|
||||||
|
- "--a_long_option"
|
||||||
|
- "--a_long_option=value"
|
||||||
|
- "--a_long_option value"
|
||||||
|
will be preserved as is when the option is not known.
|
||||||
|
|
||||||
|
For 'short' options (-S), support for @c my_getopt_skip_unknown
|
||||||
|
comes with some limitation, because several short options
|
||||||
|
can also be specified together in the same command line argument,
|
||||||
|
as in "-XYZ".
|
||||||
|
|
||||||
|
The first use case supported is: all short options are declared.
|
||||||
|
handle_options() will be able to interpret "-XYZ" as one of:
|
||||||
|
- an unknown X option
|
||||||
|
- "-X -Y -Z", three short options with no arguments
|
||||||
|
- "-X -YZ", where Y is a short option with argument Z
|
||||||
|
- "-XYZ", where X is a short option with argument YZ
|
||||||
|
based on the full short options specifications.
|
||||||
|
|
||||||
|
The second use case supported is: no short option is declared.
|
||||||
|
handle_options() will reject "-XYZ" as unknown, to be parsed later.
|
||||||
|
|
||||||
|
The use case that is explicitly not supported is to provide
|
||||||
|
only a partial list of short options to handle_options().
|
||||||
|
This function can not be expected to extract some option Y
|
||||||
|
in the middle of the string "-XYZ" in these conditions,
|
||||||
|
without knowing if X will be declared an option later.
|
||||||
|
|
||||||
|
Note that this limitation only impacts parsing of several
|
||||||
|
short options from the same command line argument,
|
||||||
|
as in "mysqld -anW5".
|
||||||
|
When each short option is properly separated out in the command line
|
||||||
|
argument, for example in "mysqld -a -n -w5", the code would actually
|
||||||
|
work even with partial options specs given at each stage.
|
||||||
|
|
||||||
@param [in, out] argc command line options (count)
|
@param [in, out] argc command line options (count)
|
||||||
@param [in, out] argv command line options (values)
|
@param [in, out] argv command line options (values)
|
||||||
@param [in] longopts descriptor of all valid options
|
@param [in] longopts descriptor of all valid options
|
||||||
@ -464,14 +507,57 @@ int handle_options(int *argc, char ***argv,
|
|||||||
}
|
}
|
||||||
if (!opt_found)
|
if (!opt_found)
|
||||||
{
|
{
|
||||||
if (my_getopt_print_errors)
|
if (my_getopt_skip_unknown)
|
||||||
my_getopt_error_reporter(ERROR_LEVEL,
|
{
|
||||||
"%s: unknown option '-%c'",
|
/*
|
||||||
my_progname, *optend);
|
We are currently parsing a single argv[] argument
|
||||||
return EXIT_UNKNOWN_OPTION;
|
of the form "-XYZ", and parsing is done in multiple phases.
|
||||||
|
One or the argument found is not an option.
|
||||||
|
*/
|
||||||
|
if (optend == cur_arg)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The first argument, "-X", is not an option
|
||||||
|
In this case, the entire argument "-XYZ" is rejected
|
||||||
|
from this phase, and preserved as is for later parsing.
|
||||||
|
*/
|
||||||
|
(*argv)[argvpos++]= *pos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We are in the middle of an "-XYZ" string already,
|
||||||
|
"-X" has already been parsed, and "Y" (pointed by optend)
|
||||||
|
is not an option.
|
||||||
|
Hack the string "-XYZ" to make a "-YZ" substring in it,
|
||||||
|
and push that to the next parsing phase.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(optend > *pos);
|
||||||
|
DBUG_ASSERT(optend > cur_arg);
|
||||||
|
DBUG_ASSERT(optend <= *pos + strlen(*pos));
|
||||||
|
DBUG_ASSERT(*optend);
|
||||||
|
optend--;
|
||||||
|
optend[0]= '-'; /* replace 'X' by '-' */
|
||||||
|
(*argv)[argvpos++]= optend;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Do not continue to parse at the current "-XYZ" argument,
|
||||||
|
skip to the next argv[] argument instead.
|
||||||
|
*/
|
||||||
|
optend= (char*) " ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (my_getopt_print_errors)
|
||||||
|
my_getopt_error_reporter(ERROR_LEVEL,
|
||||||
|
"%s: unknown option '-%c'",
|
||||||
|
my_progname, *optend);
|
||||||
|
return EXIT_UNKNOWN_OPTION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(*argc)--; /* option handled (short), decrease argument count */
|
if (opt_found)
|
||||||
|
(*argc)--; /* option handled (short), decrease argument count */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ((error= setval(optp, value, argument, set_maximum_value)))
|
if ((error= setval(optp, value, argument, set_maximum_value)))
|
||||||
@ -479,7 +565,7 @@ int handle_options(int *argc, char ***argv,
|
|||||||
if (get_one_option && get_one_option(optp->id, optp, argument))
|
if (get_one_option && get_one_option(optp->id, optp, argument))
|
||||||
return EXIT_UNSPECIFIED_ERROR;
|
return EXIT_UNSPECIFIED_ERROR;
|
||||||
|
|
||||||
(*argc)--; /* option handled (short or long), decrease argument count */
|
(*argc)--; /* option handled (long), decrease argument count */
|
||||||
}
|
}
|
||||||
else /* non-option found */
|
else /* non-option found */
|
||||||
(*argv)[argvpos++]= cur_arg;
|
(*argv)[argvpos++]= cur_arg;
|
||||||
|
@ -153,6 +153,17 @@ sys_var::sys_var(sys_var_chain *chain, const char *name_arg,
|
|||||||
guard(lock), offset(off), on_check(on_check_func), on_update(on_update_func),
|
guard(lock), offset(off), on_check(on_check_func), on_update(on_update_func),
|
||||||
is_os_charset(FALSE)
|
is_os_charset(FALSE)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
There is a limitation in handle_options() related to short options:
|
||||||
|
- either all short options should be declared when parsing in multiple stages,
|
||||||
|
- or none should be declared.
|
||||||
|
Because a lot of short options are used in the normal parsing phase
|
||||||
|
for mysqld, we enforce here that no short option is present
|
||||||
|
in the first (PARSE_EARLY) stage.
|
||||||
|
See handle_options() for details.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(parse_flag == PARSE_NORMAL || getopt_id <= 0 || getopt_id >= 255);
|
||||||
|
|
||||||
name.str= name_arg;
|
name.str= name_arg;
|
||||||
name.length= strlen(name_arg);
|
name.length= strlen(name_arg);
|
||||||
DBUG_ASSERT(name.length <= NAME_CHAR_LEN);
|
DBUG_ASSERT(name.length <= NAME_CHAR_LEN);
|
||||||
|
Reference in New Issue
Block a user