From 19c21d115d221d9738afad142f2886dfd3cc40de Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Mon, 6 Mar 2006 19:49:20 +0000 Subject: Enable standard_conforming_strings to be turned on. Kevin Grittner --- src/backend/parser/scan.l | 100 ++++++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 39 deletions(-) (limited to 'src/backend/parser') 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); * extended C-style comments * delimited identifiers (double-quoted identifiers) * hexadecimal numeric string - * quoted strings + * standard quoted strings + * extended quoted strings (support backslash escape sequences) * $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(); } -{quotestop} | -{quotefail} { +{quotestop} | +{quotefail} { yyless(1); BEGIN(INITIAL); yylval.str = litbufdup(); return SCONST; } -{xqdouble} { +{xqdouble} { addlitchar('\''); } {xqinside} { addlit(yytext, yyleng); } -{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(); +{xeinside} { + addlit(yytext, yyleng); + } +{xqbackslash} { + check_string_escape_warning(yytext[1]); + addlitchar('\\'); + } +{xeescape} { + check_string_escape_warning(yytext[1]); addlitchar(unescape_single_char(yytext[1])); } -{xqoctesc} { +{xeoctesc} { unsigned char c = strtoul(yytext+1, NULL, 8); check_escape_warning(); addlitchar(c); } -{xqhexesc} { +{xehexesc} { unsigned char c = strtoul(yytext+2, NULL, 16); check_escape_warning(); addlitchar(c); } -{quotecontinue} { +{quotecontinue} { /* ignore */ } -. { +. { /* This is only needed for \ just before EOF */ addlitchar(yytext[0]); } -<> { yyerror("unterminated quoted string"); } +<> { yyerror("unterminated quoted string"); } {dolqdelim} { token_start = yytext; @@ -875,6 +870,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) { -- cgit v1.2.3