2424 * Portions Copyright (c) 1994, Regents of the University of California
2525 *
2626 * IDENTIFICATION
27- * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.126 2005/06/2603:03:38 momjian Exp $
27+ * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.127 2005/06/2619:16:05 tgl Exp $
2828 *
2929 *-------------------------------------------------------------------------
3030*/
4848extern YYSTYPE yylval;
4949
5050static int xcdepth =0 ;/* depth of nesting in slash-star comments*/
51- static char *dolqstart;/* current $foo$ quote start string*/
52- static bool warn_on_first_escape;
51+ static char *dolqstart;/* current $foo$ quote start string*/
52+
53+ /*
54+ * GUC variable. This is a DIRECT violation of the warning given at the
55+ * head of gram.y, ie flex/bison code must not depend on any GUC variables;
56+ * as such, changing its value can induce very unintuitive behavior.
57+ * But we shall have to live with it as a short-term thing until the switch
58+ * to SQL-standard string syntax is complete.
59+ */
5360bool escape_string_warning;
5461
62+ static bool warn_on_first_escape;
63+
5564/*
5665 * literalbuf is used to accumulate literal values when multiple rules
5766 * are needed to parse a single literal. Call startlit to reset buffer
@@ -66,6 +75,7 @@ static intliteralalloc;/* current allocated buffer size */
6675static void addlit (char *ytext,int yleng);
6776static void addlitchar (unsigned char ychar);
6877static char *litbufdup (void );
78+ static int pg_err_position (void );
6979static void check_escape_warning (void );
7080
7181/*
@@ -188,9 +198,8 @@ xhinside[^']*
188198/* National character */
189199xnstart [nN ]{quote }
190200
191- /*Quote stringdoes not warn about escapes */
201+ /*Quoted stringthat allows backslash escapes */
192202xestart [eE ]{quote }
193- xeinside [^ ' ]*
194203
195204/* Extended quote
196205 * xqdouble implements embedded quote, ''''
@@ -446,17 +455,21 @@ other.
446455{
447456if (warn_on_first_escape && escape_string_warning)
448457ereport (WARNING,
449- (errcode (ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER),
450- errmsg (" Invalid use of\\ ' in a normal string" ),
451- errhint (" Use '' to place quotes in strings, or use the escape string syntax (E'')." )));
458+ (errcode (ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
459+ errmsg (" nonstandard use of\\ ' in a string literal" ),
460+ errhint (" Use '' to write quotes in strings, or use the escape string syntax (E'...')." ),
461+ errposition (pg_err_position ())));
462+ warn_on_first_escape =false ;/* warn only once per string */
452463}
453464else if (yytext[1 ] ==' \\ ' )
454465{
455466if (warn_on_first_escape && escape_string_warning)
456467ereport (WARNING,
457- (errcode (ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER),
458- errmsg (" Invalid use of\\\\ in a normal string" ),
459- errhint (" Use the escape string syntax for backslashes, e.g. E'\\\\ '." )));
468+ (errcode (ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
469+ errmsg (" nonstandard use of\\\\ in a string literal" ),
470+ errhint (" Use the escape string syntax for backslashes, e.g., E'\\\\ '." ),
471+ errposition (pg_err_position ())));
472+ warn_on_first_escape =false ;/* warn only once per string */
460473}
461474else
462475check_escape_warning ();
@@ -707,14 +720,20 @@ other.
707720
708721%%
709722
710- void
711- yyerror ( const char *message )
723+ static int
724+ pg_err_position ( void )
712725{
713726const char *loc = token_start ? token_start : yytext;
714- int cursorpos;
715727
716728/* in multibyte encodings, return index in characters not bytes */
717- cursorpos =pg_mbstrlen_with_len (scanbuf, loc - scanbuf) +1 ;
729+ return pg_mbstrlen_with_len (scanbuf, loc - scanbuf) +1 ;
730+ }
731+
732+ void
733+ yyerror (const char *message)
734+ {
735+ const char *loc = token_start ? token_start : yytext;
736+ int cursorpos =pg_err_position ();
718737
719738if (*loc == YY_END_OF_BUFFER_CHAR)
720739{
@@ -852,8 +871,9 @@ check_escape_warning(void)
852871{
853872if (warn_on_first_escape && escape_string_warning)
854873ereport (WARNING,
855- (errcode (ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER),
856- errmsg (" Invalid use of escapes in an ordinary string" ),
857- errhint (" Use the escape string syntax for escapes, e.g. E'\\ r\\ n'." )));
874+ (errcode (ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
875+ errmsg (" nonstandard use of escape in a string literal" ),
876+ errhint (" Use the escape string syntax for escapes, e.g., E'\\ r\\ n'." ),
877+ errposition (pg_err_position ())));
858878warn_on_first_escape =false ;/* warn only once per string */
859879}