diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/parser/scan.l | 100 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 7 | ||||
-rw-r--r-- | src/backend/utils/misc/postgresql.conf.sample | 3 |
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 |