aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/parser/scan.l100
-rw-r--r--src/backend/utils/misc/guc.c7
-rw-r--r--src/backend/utils/misc/postgresql.conf.sample3
3 files changed, 66 insertions, 44 deletions
diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l
index 10193bcff59..e277920ee20 100644
--- a/src/backend/parser/scan.l
+++ b/src/backend/parser/scan.l
@@ -24,7 +24,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.130 2006/03/05 15:58:34 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.131 2006/03/06 19:49:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -51,13 +51,14 @@ static int xcdepth = 0; /* depth of nesting in slash-star comments */
static char *dolqstart; /* current $foo$ quote start string */
/*
- * GUC variable. This is a DIRECT violation of the warning given at the
+ * GUC variables. This is a DIRECT violation of the warning given at the
* head of gram.y, ie flex/bison code must not depend on any GUC variables;
* as such, changing its value can induce very unintuitive behavior.
* But we shall have to live with it as a short-term thing until the switch
* to SQL-standard string syntax is complete.
*/
bool escape_string_warning;
+bool standard_conforming_strings;
static bool warn_on_first_escape;
@@ -77,6 +78,7 @@ static void addlitchar(unsigned char ychar);
static char *litbufdup(void);
static int pg_err_position(void);
static void check_escape_warning(void);
+static void check_string_escape_warning(unsigned char ychar);
/*
* When we parse a token that requires multiple lexer rules to process,
@@ -119,7 +121,8 @@ static unsigned char unescape_single_char(unsigned char c);
* <xc> extended C-style comments
* <xd> delimited identifiers (double-quoted identifiers)
* <xh> hexadecimal numeric string
- * <xq> quoted strings
+ * <xq> standard quoted strings
+ * <xe> extended quoted strings (support backslash escape sequences)
* <xdolq> $foo$ quoted strings
*/
@@ -127,6 +130,7 @@ static unsigned char unescape_single_char(unsigned char c);
%x xc
%x xd
%x xh
+%x xe
%x xq
%x xdolq
@@ -200,6 +204,10 @@ xnstart [nN]{quote}
/* Quoted string that allows backslash escapes */
xestart [eE]{quote}
+xeinside [^\\']+
+xeescape [\\][^0-7]
+xeoctesc [\\][0-7]{1,3}
+xehexesc [\\]x[0-9A-Fa-f]{1,2}
/* Extended quote
* xqdouble implements embedded quote, ''''
@@ -207,9 +215,7 @@ xestart [eE]{quote}
xqstart {quote}
xqdouble {quote}{quote}
xqinside [^\\']+
-xqescape [\\][^0-7]
-xqoctesc [\\][0-7]{1,3}
-xqhexesc [\\]x[0-9A-Fa-f]{1,2}
+xqbackslash [\\]
/* $foo$ style quotes ("dollar quoting")
* The quoted string starts with $foo$ where "foo" is an optional string
@@ -428,73 +434,62 @@ other .
{xqstart} {
warn_on_first_escape = true;
token_start = yytext;
- BEGIN(xq);
+ if (standard_conforming_strings)
+ BEGIN(xq);
+ else
+ BEGIN(xe);
startlit();
}
{xestart} {
warn_on_first_escape = false;
token_start = yytext;
- BEGIN(xq);
+ BEGIN(xe);
startlit();
}
-<xq>{quotestop} |
-<xq>{quotefail} {
+<xq,xe>{quotestop} |
+<xq,xe>{quotefail} {
yyless(1);
BEGIN(INITIAL);
yylval.str = litbufdup();
return SCONST;
}
-<xq>{xqdouble} {
+<xq,xe>{xqdouble} {
addlitchar('\'');
}
<xq>{xqinside} {
addlit(yytext, yyleng);
}
-<xq>{xqescape} {
- if (yytext[1] == '\'')
- {
- if (warn_on_first_escape && escape_string_warning)
- ereport(WARNING,
- (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
- errmsg("nonstandard use of \\' in a string literal"),
- errhint("Use '' to write quotes in strings, or use the escape string syntax (E'...')."),
- errposition(pg_err_position())));
- warn_on_first_escape = false; /* warn only once per string */
- }
- else if (yytext[1] == '\\')
- {
- if (warn_on_first_escape && escape_string_warning)
- ereport(WARNING,
- (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
- errmsg("nonstandard use of \\\\ in a string literal"),
- errhint("Use the escape string syntax for backslashes, e.g., E'\\\\'."),
- errposition(pg_err_position())));
- warn_on_first_escape = false; /* warn only once per string */
- }
- else
- check_escape_warning();
+<xe>{xeinside} {
+ addlit(yytext, yyleng);
+ }
+<xq>{xqbackslash} {
+ check_string_escape_warning(yytext[1]);
+ addlitchar('\\');
+ }
+<xe>{xeescape} {
+ check_string_escape_warning(yytext[1]);
addlitchar(unescape_single_char(yytext[1]));
}
-<xq>{xqoctesc} {
+<xe>{xeoctesc} {
unsigned char c = strtoul(yytext+1, NULL, 8);
check_escape_warning();
addlitchar(c);
}
-<xq>{xqhexesc} {
+<xe>{xehexesc} {
unsigned char c = strtoul(yytext+2, NULL, 16);
check_escape_warning();
addlitchar(c);
}
-<xq>{quotecontinue} {
+<xq,xe>{quotecontinue} {
/* ignore */
}
-<xq>. {
+<xe>. {
/* This is only needed for \ just before EOF */
addlitchar(yytext[0]);
}
-<xq><<EOF>> { yyerror("unterminated quoted string"); }
+<xq,xe><<EOF>> { yyerror("unterminated quoted string"); }
{dolqdelim} {
token_start = yytext;
@@ -876,6 +871,33 @@ unescape_single_char(unsigned char c)
}
static void
+check_string_escape_warning(unsigned char ychar)
+{
+ if (ychar == '\'')
+ {
+ if (warn_on_first_escape && escape_string_warning)
+ ereport(WARNING,
+ (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
+ errmsg("nonstandard use of \\' in a string literal"),
+ errhint("Use '' to write quotes in strings, or use the escape string syntax (E'...')."),
+ errposition(pg_err_position())));
+ warn_on_first_escape = false; /* warn only once per string */
+ }
+ else if (ychar == '\\')
+ {
+ if (warn_on_first_escape && escape_string_warning)
+ ereport(WARNING,
+ (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
+ errmsg("nonstandard use of \\\\ in a string literal"),
+ errhint("Use the escape string syntax for backslashes, e.g., E'\\\\'."),
+ errposition(pg_err_position())));
+ warn_on_first_escape = false; /* warn only once per string */
+ }
+ else
+ check_escape_warning();
+}
+
+static void
check_escape_warning(void)
{
if (warn_on_first_escape && escape_string_warning)
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 67eb67144f0..16180247bfc 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.312 2006/03/05 15:58:49 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.313 2006/03/06 19:49:20 momjian Exp $
*
*--------------------------------------------------------------------
*/
@@ -224,7 +224,6 @@ static int max_index_keys;
static int max_identifier_length;
static int block_size;
static bool integer_datetimes;
-static bool standard_conforming_strings;
/* should be static, but commands/variable.c needs to get at these */
char *role_string;
@@ -974,10 +973,10 @@ static struct config_bool ConfigureNamesBool[] =
},
{
- {"standard_conforming_strings", PGC_INTERNAL, PRESET_OPTIONS,
+ {"standard_conforming_strings", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
gettext_noop("'...' strings treat backslashes literally."),
NULL,
- GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
+ GUC_REPORT
},
&standard_conforming_strings,
false, NULL, NULL
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 731f9ff6c2e..071839cfd89 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -415,7 +415,8 @@
#add_missing_from = off
#array_nulls = on
#default_with_oids = off
-#escape_string_warning = off
+#escape_string_warning = off # warn about backslashes in string literals
+#standard_conforming_strings = off # SQL standard string literal processing
#regex_flavor = advanced # advanced, extended, or basic
#sql_inheritance = on