mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-03-07 19:47:50 +08:00
Fix postgresql.conf lexer to accept doubled single quotes in literal
strings. This is consistent with SQL conventions, and since Bruce already changed initdb in a way that assumed it worked like this, seems we'd better make it work like this.
This commit is contained in:
parent
dbf952860e
commit
1128f55659
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.18 2005/09/19 17:21:46 momjian Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.19 2005/09/21 20:33:33 tgl Exp $
|
||||
-->
|
||||
<chapter Id="runtime-config">
|
||||
<title>Run-time Configuration</title>
|
||||
@ -45,7 +45,8 @@ search_path = '$user, public'
|
||||
value is optional. Whitespace is insignificant and blank lines are
|
||||
ignored. Hash marks (<literal>#</literal>) introduce comments
|
||||
anywhere. Parameter values that are not simple identifiers or
|
||||
numbers must be single-quoted.
|
||||
numbers must be single-quoted. To embed a single quote in a parameter
|
||||
value, write either two quotes (preferred) or backslash-quote.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Copyright (c) 2000-2005, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.31 2005/07/08 18:41:40 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.32 2005/09/21 20:33:34 tgl Exp $
|
||||
*/
|
||||
|
||||
%{
|
||||
@ -38,7 +38,7 @@ enum {
|
||||
|
||||
/* prototype, so compiler is happy with our high warnings setting */
|
||||
int GUC_yylex(void);
|
||||
static char *GUC_scanstr(char *);
|
||||
static char *GUC_scanstr(const char *s);
|
||||
%}
|
||||
|
||||
%option 8bit
|
||||
@ -64,7 +64,7 @@ ID {LETTER}{LETTER_OR_DIGIT}*
|
||||
QUALIFIED_ID {ID}"."{ID}
|
||||
|
||||
UNQUOTED_STRING {LETTER}({LETTER_OR_DIGIT}|[-._:/])*
|
||||
STRING \'([^'\n]|\\.)*\'
|
||||
STRING \'([^'\\\n]|\\.|\'\')*\'
|
||||
|
||||
%%
|
||||
|
||||
@ -181,22 +181,16 @@ ProcessConfigFile(GucContext context)
|
||||
if (token == GUC_EQUALS)
|
||||
token = yylex();
|
||||
|
||||
if (token != GUC_ID && token != GUC_STRING &&
|
||||
if (token != GUC_ID &&
|
||||
token != GUC_STRING &&
|
||||
token != GUC_INTEGER &&
|
||||
token != GUC_REAL &&
|
||||
token != GUC_UNQUOTED_STRING)
|
||||
goto parse_error;
|
||||
opt_value = pstrdup(yytext);
|
||||
if (token == GUC_STRING)
|
||||
{
|
||||
/* remove the beginning and ending quote/apostrophe */
|
||||
/* first: shift the whole thing down one character */
|
||||
memmove(opt_value, opt_value+1, strlen(opt_value)-1);
|
||||
/* second: null out the 2 characters we shifted */
|
||||
opt_value[strlen(opt_value)-2] = '\0';
|
||||
/* do the escape thing. pfree()'s the pstrdup above */
|
||||
opt_value = GUC_scanstr(opt_value);
|
||||
}
|
||||
if (token == GUC_STRING) /* strip quotes and escapes */
|
||||
opt_value = GUC_scanstr(yytext);
|
||||
else
|
||||
opt_value = pstrdup(yytext);
|
||||
parse_state = 2;
|
||||
break;
|
||||
|
||||
@ -280,34 +274,33 @@ ProcessConfigFile(GucContext context)
|
||||
|
||||
|
||||
|
||||
/* ----------------
|
||||
/*
|
||||
* scanstr
|
||||
*
|
||||
* if the string passed in has escaped codes, map the escape codes to actual
|
||||
* chars
|
||||
* Strip the quotes surrounding the given string, and collapse any embedded
|
||||
* '' sequences and backslash escapes.
|
||||
*
|
||||
* the string returned is palloc'd and should eventually be pfree'd by the
|
||||
* caller; also we assume we should pfree the input string.
|
||||
* ----------------
|
||||
* caller.
|
||||
*/
|
||||
|
||||
static char *
|
||||
GUC_scanstr(char *s)
|
||||
GUC_scanstr(const char *s)
|
||||
{
|
||||
char *newStr;
|
||||
int len,
|
||||
i,
|
||||
j;
|
||||
|
||||
if (s == NULL || s[0] == '\0')
|
||||
{
|
||||
if (s != NULL)
|
||||
pfree(s);
|
||||
return pstrdup("");
|
||||
}
|
||||
Assert(s != NULL && s[0] == '\'');
|
||||
len = strlen(s);
|
||||
Assert(len >= 2);
|
||||
Assert(s[len-1] == '\'');
|
||||
|
||||
newStr = palloc(len + 1); /* string cannot get longer */
|
||||
/* Skip the leading quote; we'll handle the trailing quote below */
|
||||
s++, len--;
|
||||
|
||||
/* Since len still includes trailing quote, this is enough space */
|
||||
newStr = palloc(len);
|
||||
|
||||
for (i = 0, j = 0; i < len; i++)
|
||||
{
|
||||
@ -354,13 +347,21 @@ GUC_scanstr(char *s)
|
||||
default:
|
||||
newStr[j] = s[i];
|
||||
break;
|
||||
}
|
||||
} /* switch */
|
||||
}
|
||||
else if (s[i] == '\'' && s[i+1] == '\'')
|
||||
{
|
||||
/* doubled quote becomes just one quote */
|
||||
newStr[j] = s[++i];
|
||||
}
|
||||
else
|
||||
newStr[j] = s[i];
|
||||
j++;
|
||||
}
|
||||
newStr[j] = '\0';
|
||||
pfree(s);
|
||||
|
||||
/* We copied the ending quote to newStr, so replace with \0 */
|
||||
Assert(j > 0 && j <= len);
|
||||
newStr[--j] = '\0';
|
||||
|
||||
return newStr;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user