mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
Allow escaping of option values for options passed at connection start.
This is useful to allow to set GUCs to values that include spaces; something that wasn't previously possible. The primary case motivating this is the desire to set default_transaction_isolation to 'repeatable read' on a per connection basis, but other usecases like seach_path do also exist. This introduces a slight backward incompatibility: Previously a \ in an option value would have been passed on literally, now it'll be taken as an escape. The relevant mailing list discussion starts with 20140204125823.GJ12016@awork2.anarazel.de.
This commit is contained in:
parent
e23014f3d4
commit
11a020eb6e
@ -4734,7 +4734,10 @@ StartupMessage (F)
|
||||
set at backend start time might be listed. Such settings
|
||||
will be applied during backend start (after parsing the
|
||||
command-line options if any). The values will act as
|
||||
session defaults.
|
||||
session defaults. Spaces in option values need to be escaped
|
||||
with a backslash (<literal>\</>). A literal backslash can be
|
||||
passed by escaping it with another backslash
|
||||
(i.e <literal>\\</>).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -4083,8 +4083,7 @@ BackendRun(Port *port)
|
||||
|
||||
/*
|
||||
* Pass any backend switches specified with -o on the postmaster's own
|
||||
* command line. We assume these are secure. (It's OK to mangle
|
||||
* ExtraOptions now, since we're safely inside a subprocess.)
|
||||
* command line. We assume these are secure.
|
||||
*/
|
||||
pg_split_opts(av, &ac, ExtraOptions);
|
||||
|
||||
|
@ -409,32 +409,57 @@ InitCommunication(void)
|
||||
/*
|
||||
* pg_split_opts -- split a string of options and append it to an argv array
|
||||
*
|
||||
* NB: the input string is destructively modified! Also, caller is responsible
|
||||
* for ensuring the argv array is large enough. The maximum possible number
|
||||
* of arguments added by this routine is (strlen(optstr) + 1) / 2.
|
||||
* The caller is responsible for ensuring the argv array is large enough. The
|
||||
* maximum possible number of arguments added by this routine is
|
||||
* (strlen(optstr) + 1) / 2.
|
||||
*
|
||||
* Since no current POSTGRES arguments require any quoting characters,
|
||||
* we can use the simple-minded tactic of assuming each set of space-
|
||||
* delimited characters is a separate argv element.
|
||||
*
|
||||
* If you don't like that, well, we *used* to pass the whole option string
|
||||
* as ONE argument to execl(), which was even less intelligent...
|
||||
* Because some option values can contain spaces we allow escaping using
|
||||
* backslashes, with \\ representing a literal backslash.
|
||||
*/
|
||||
void
|
||||
pg_split_opts(char **argv, int *argcp, char *optstr)
|
||||
{
|
||||
StringInfoData s;
|
||||
|
||||
initStringInfo(&s);
|
||||
|
||||
while (*optstr)
|
||||
{
|
||||
bool last_was_escape = false;
|
||||
|
||||
resetStringInfo(&s);
|
||||
|
||||
/* skip over leading space */
|
||||
while (isspace((unsigned char) *optstr))
|
||||
optstr++;
|
||||
|
||||
if (*optstr == '\0')
|
||||
break;
|
||||
argv[(*argcp)++] = optstr;
|
||||
while (*optstr && !isspace((unsigned char) *optstr))
|
||||
optstr++;
|
||||
if (*optstr)
|
||||
*optstr++ = '\0';
|
||||
|
||||
/*
|
||||
* Parse a single option + value, stopping at the first space, unless
|
||||
* it's escaped.
|
||||
*/
|
||||
while (*optstr)
|
||||
{
|
||||
if (isspace(*optstr) && !last_was_escape)
|
||||
break;
|
||||
|
||||
if (!last_was_escape && *optstr == '\\')
|
||||
last_was_escape = true;
|
||||
else
|
||||
{
|
||||
last_was_escape = false;
|
||||
appendStringInfoChar(&s, *optstr);
|
||||
}
|
||||
|
||||
optstr++;
|
||||
}
|
||||
|
||||
/* now store the option */
|
||||
argv[(*argcp)++] = pstrdup(s.data);
|
||||
}
|
||||
resetStringInfo(&s);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -981,7 +1006,6 @@ process_startup_options(Port *port, bool am_superuser)
|
||||
|
||||
av[ac++] = "postgres";
|
||||
|
||||
/* Note this mangles port->cmdline_options */
|
||||
pg_split_opts(av, &ac, port->cmdline_options);
|
||||
|
||||
av[ac] = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user