Commit d395aecf authored by Tom Lane's avatar Tom Lane

Code review for escape-strings patch. Sync psql and plpgsql lexers

with main, avoid using a SQL-defined SQLSTATE for what is most definitely
not a SQL-compatible error condition, fix documentation omissions,
adhere to message style guidelines, don't use two GUC_REPORT variables
when one is sufficient.  Nothing done about pg_dump issues.
parent 3cbd6bc3
<!-- $PostgreSQL: pgsql/doc/src/sgml/errcodes.sgml,v 1.12 2005/01/06 01:49:24 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/errcodes.sgml,v 1.13 2005/06/26 19:16:04 tgl Exp $ -->
<appendix id="errcodes-appendix"> <appendix id="errcodes-appendix">
<title><productname>PostgreSQL</productname> Error Codes</title> <title><productname>PostgreSQL</productname> Error Codes</title>
...@@ -370,6 +370,11 @@ ...@@ -370,6 +370,11 @@
<entry>INVALID ESCAPE SEQUENCE</entry> <entry>INVALID ESCAPE SEQUENCE</entry>
</row> </row>
<row>
<entry><literal>22P06</literal></entry>
<entry>NONSTANDARD USE OF ESCAPE CHARACTER</entry>
</row>
<row> <row>
<entry><literal>22010</literal></entry> <entry><literal>22010</literal></entry>
<entry>INVALID INDICATOR PARAMETER VALUE</entry> <entry>INVALID INDICATOR PARAMETER VALUE</entry>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.186 2005/06/21 04:02:29 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.187 2005/06/26 19:16:04 tgl Exp $
--> -->
<chapter id="libpq"> <chapter id="libpq">
...@@ -286,7 +286,7 @@ PGconn *PQconnectdb(const char *conninfo); ...@@ -286,7 +286,7 @@ PGconn *PQconnectdb(const char *conninfo);
Kerberos service name to use when authenticating with Kerberos 4 or 5. Kerberos service name to use when authenticating with Kerberos 4 or 5.
This must match the service name specified in the server This must match the service name specified in the server
configuration for Kerberos authentication to succeed. (See also configuration for Kerberos authentication to succeed. (See also
<xref linkend="kerberos-auth">.) <xref linkend="kerberos-auth">.)
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -888,10 +888,13 @@ Parameters reported as of the current release include ...@@ -888,10 +888,13 @@ Parameters reported as of the current release include
<literal>is_superuser</>, <literal>is_superuser</>,
<literal>session_authorization</>, <literal>session_authorization</>,
<literal>DateStyle</>, <literal>DateStyle</>,
<literal>TimeZone</>, and <literal>TimeZone</>,
<literal>integer_datetimes</>. <literal>integer_datetimes</>, and
<literal>standard_compliant_strings</>.
(<literal>server_encoding</>, <literal>TimeZone</>, and (<literal>server_encoding</>, <literal>TimeZone</>, and
<literal>integer_datetimes</> were not reported by releases before 8.0.) <literal>integer_datetimes</> were not reported by releases before 8.0;
<literal>standard_compliant_strings</> was not reported by releases
before 8.1.)
Note that Note that
<literal>server_version</>, <literal>server_version</>,
<literal>server_encoding</> and <literal>server_encoding</> and
...@@ -913,6 +916,14 @@ see also <function>PQserverVersion</>, which returns the information ...@@ -913,6 +916,14 @@ see also <function>PQserverVersion</>, which returns the information
in a numeric form that is much easier to compare against. in a numeric form that is much easier to compare against.
</para> </para>
<para>
If no value for <literal>standard_compliant_strings</> is reported,
applications may assume it is <literal>false</>, that is, backslashes
are treated as escapes in string literals. Also, the presence of this
parameter may be taken as an indication that the escape string syntax
(<literal>E'...'</>) is accepted.
</para>
<para> <para>
Although the returned pointer is declared <literal>const</>, it in fact Although the returned pointer is declared <literal>const</>, it in fact
points to mutable storage associated with the <literal>PGconn</> structure. points to mutable storage associated with the <literal>PGconn</> structure.
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/protocol.sgml,v 1.59 2005/06/22 15:19:43 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/protocol.sgml,v 1.60 2005/06/26 19:16:04 tgl Exp $ -->
<chapter id="protocol"> <chapter id="protocol">
<title>Frontend/Backend Protocol</title> <title>Frontend/Backend Protocol</title>
...@@ -1072,10 +1072,13 @@ ...@@ -1072,10 +1072,13 @@
<literal>is_superuser</>, <literal>is_superuser</>,
<literal>session_authorization</>, <literal>session_authorization</>,
<literal>DateStyle</>, <literal>DateStyle</>,
<literal>TimeZone</>, and <literal>TimeZone</>,
<literal>integer_datetimes</>. <literal>integer_datetimes</>, and
<literal>standard_compliant_strings</>.
(<literal>server_encoding</>, <literal>TimeZone</>, and (<literal>server_encoding</>, <literal>TimeZone</>, and
<literal>integer_datetimes</> were not reported by releases before 8.0.) <literal>integer_datetimes</> were not reported by releases before 8.0;
<literal>standard_compliant_strings</> was not reported by releases
before 8.1.)
Note that Note that
<literal>server_version</>, <literal>server_version</>,
<literal>server_encoding</> and <literal>server_encoding</> and
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.331 2005/06/26 03:03:17 momjian Exp $ $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.332 2005/06/26 19:16:04 tgl Exp $
--> -->
<chapter Id="runtime"> <chapter Id="runtime">
...@@ -3766,13 +3766,11 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' ...@@ -3766,13 +3766,11 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
<listitem> <listitem>
<para> <para>
When <literal>on</>, a warning is issued if a backslash When <literal>on</>, a warning is issued if a backslash
(<literal>\</>) appears in a ordinary, non-escape syntax (<literal>\</>) appears in an ordinary string literal
(<literal>''</>) string. To log the statement that generated the (<literal>'...'</> syntax). The default is <literal>off</>.
warning, set <varname>log_min_error_statement</> to
<literal>error</>. The default is off.
</para> </para>
<para> <para>
Escape string syntax (<literal>E''</>) should be used for Escape string syntax (<literal>E'...'</>) should be used for
escapes, because in future versions of escapes, because in future versions of
<productname>PostgreSQL</productname> ordinary strings will have <productname>PostgreSQL</productname> ordinary strings will have
the standard-compliant behavior of treating backslashes the standard-compliant behavior of treating backslashes
...@@ -3988,22 +3986,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' ...@@ -3988,22 +3986,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="guc-escape-string-syntax" xreflabel="escape_string_syntax"> <varlistentry id="guc-standard-compliant-strings" xreflabel="standard_compliant_strings">
<term><varname>escape_string_syntax</varname> (<type>boolean</type>)</term>
<indexterm><primary>strings</><secondary>escape</></>
<indexterm>
<primary><varname>escape_string_syntax</> configuration parameter</primary>
</indexterm>
<listitem>
<para>
Reports whether escape string syntax (<literal>E''</>) is
supported. This variable is used by applications that need to
determine if escape string syntax can be used in their code.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-sql-standard-strings" xreflabel="standard_compliant_strings">
<term><varname>standard_compliant_strings</varname> (<type>boolean</type>)</term> <term><varname>standard_compliant_strings</varname> (<type>boolean</type>)</term>
<indexterm><primary>strings</><secondary>escape</></> <indexterm><primary>strings</><secondary>escape</></>
<indexterm> <indexterm>
...@@ -4011,10 +3994,16 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' ...@@ -4011,10 +3994,16 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
</indexterm> </indexterm>
<listitem> <listitem>
<para> <para>
Reports whether ordinary, non-escape syntax strings Reports whether ordinary string literals
(<literal>''</>) treat backslashes literally, as specified in (<literal>'...'</>) treat backslashes literally, as specified in
the SQL standard. This variable is used by applications that the SQL standard. The value is currently always <literal>false</>,
need to know how ordinary strings are processed`. indicating that backslashes are treated as escapes. It is planned
that this will change to <literal>true</> in a future
<productname>PostgreSQL</productname> release when string literal
syntax changes to meet the standard. Applications may check this
parameter to determine how string literals will be processed.
The presence of this parameter can also be taken as an indication
that the escape string syntax (<literal>E'...'</>) is supported.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/syntax.sgml,v 1.101 2005/06/26 03:03:21 momjian Exp $ $PostgreSQL: pgsql/doc/src/sgml/syntax.sgml,v 1.102 2005/06/26 19:16:05 tgl Exp $
--> -->
<chapter id="sql-syntax"> <chapter id="sql-syntax">
...@@ -249,7 +249,7 @@ UPDATE "my_table" SET "a" = 5; ...@@ -249,7 +249,7 @@ UPDATE "my_table" SET "a" = 5;
<productname>PostgreSQL</productname> also allows single quotes <productname>PostgreSQL</productname> also allows single quotes
to be escaped with a backslash (<literal>\'</literal>). However, to be escaped with a backslash (<literal>\'</literal>). However,
future versions of <productname>PostgreSQL</productname> will not future versions of <productname>PostgreSQL</productname> will not
support this so applications using this should convert to the allow this, so applications using backslashes should convert to the
standard-compliant method outlined above. standard-compliant method outlined above.
</para> </para>
...@@ -276,8 +276,8 @@ UPDATE "my_table" SET "a" = 5; ...@@ -276,8 +276,8 @@ UPDATE "my_table" SET "a" = 5;
eventually treat backslashes as literal characters to be eventually treat backslashes as literal characters to be
standard-compliant. The proper way to specify escape processing is standard-compliant. The proper way to specify escape processing is
to use the escape string syntax to indicate that escape to use the escape string syntax to indicate that escape
processing is desired. Escape string syntax is specified by placing processing is desired. Escape string syntax is specified by writing
the the letter <literal>E</literal> (upper or lower case) before the letter <literal>E</literal> (upper or lower case) just before
the string, e.g. <literal>E'\041'</>. This method will work in all the string, e.g. <literal>E'\041'</>. This method will work in all
future versions of <productname>PostgreSQL</productname>. future versions of <productname>PostgreSQL</productname>.
</para> </para>
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.126 2005/06/26 03:03:38 momjian Exp $ * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.127 2005/06/26 19:16:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -48,10 +48,19 @@ ...@@ -48,10 +48,19 @@
extern YYSTYPE yylval; extern YYSTYPE yylval;
static int xcdepth = 0; /* depth of nesting in slash-star comments */ static int xcdepth = 0; /* depth of nesting in slash-star comments */
static char *dolqstart; /* current $foo$ quote start string */ static char *dolqstart; /* current $foo$ quote start string */
static bool warn_on_first_escape;
/*
* GUC variable. 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 escape_string_warning;
static bool warn_on_first_escape;
/* /*
* literalbuf is used to accumulate literal values when multiple rules * literalbuf is used to accumulate literal values when multiple rules
* are needed to parse a single literal. Call startlit to reset buffer * are needed to parse a single literal. Call startlit to reset buffer
...@@ -66,6 +75,7 @@ static int literalalloc; /* current allocated buffer size */ ...@@ -66,6 +75,7 @@ static int literalalloc; /* current allocated buffer size */
static void addlit(char *ytext, int yleng); static void addlit(char *ytext, int yleng);
static void addlitchar(unsigned char ychar); static void addlitchar(unsigned char ychar);
static char *litbufdup(void); static char *litbufdup(void);
static int pg_err_position(void);
static void check_escape_warning(void); static void check_escape_warning(void);
/* /*
...@@ -188,9 +198,8 @@ xhinside [^']* ...@@ -188,9 +198,8 @@ xhinside [^']*
/* National character */ /* National character */
xnstart [nN]{quote} xnstart [nN]{quote}
/* Quote string does not warn about escapes */ /* Quoted string that allows backslash escapes */
xestart [eE]{quote} xestart [eE]{quote}
xeinside [^']*
/* Extended quote /* Extended quote
* xqdouble implements embedded quote, '''' * xqdouble implements embedded quote, ''''
...@@ -446,17 +455,21 @@ other . ...@@ -446,17 +455,21 @@ other .
{ {
if (warn_on_first_escape && escape_string_warning) if (warn_on_first_escape && escape_string_warning)
ereport(WARNING, ereport(WARNING,
(errcode(ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER), (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
errmsg("Invalid use of \\' in a normal string"), errmsg("nonstandard use of \\' in a string literal"),
errhint("Use '' to place quotes in strings, or use the escape string syntax (E'')."))); 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] == '\\') else if (yytext[1] == '\\')
{ {
if (warn_on_first_escape && escape_string_warning) if (warn_on_first_escape && escape_string_warning)
ereport(WARNING, ereport(WARNING,
(errcode(ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER), (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
errmsg("Invalid use of \\\\ in a normal string"), errmsg("nonstandard use of \\\\ in a string literal"),
errhint("Use the escape string syntax for backslashes, e.g. E'\\\\'."))); 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 else
check_escape_warning(); check_escape_warning();
...@@ -707,14 +720,20 @@ other . ...@@ -707,14 +720,20 @@ other .
%% %%
void static int
yyerror(const char *message) pg_err_position(void)
{ {
const char *loc = token_start ? token_start : yytext; const char *loc = token_start ? token_start : yytext;
int cursorpos;
/* in multibyte encodings, return index in characters not bytes */ /* in multibyte encodings, return index in characters not bytes */
cursorpos = pg_mbstrlen_with_len(scanbuf, loc - scanbuf) + 1; return pg_mbstrlen_with_len(scanbuf, loc - scanbuf) + 1;
}
void
yyerror(const char *message)
{
const char *loc = token_start ? token_start : yytext;
int cursorpos = pg_err_position();
if (*loc == YY_END_OF_BUFFER_CHAR) if (*loc == YY_END_OF_BUFFER_CHAR)
{ {
...@@ -852,8 +871,9 @@ check_escape_warning(void) ...@@ -852,8 +871,9 @@ check_escape_warning(void)
{ {
if (warn_on_first_escape && escape_string_warning) if (warn_on_first_escape && escape_string_warning)
ereport(WARNING, ereport(WARNING,
(errcode(ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER), (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
errmsg("Invalid use of escapes in an ordinary string"), errmsg("nonstandard use of escape in a string literal"),
errhint("Use the escape string syntax for escapes, e.g. E'\\r\\n'."))); errhint("Use the escape string syntax for escapes, e.g., E'\\r\\n'."),
errposition(pg_err_position())));
warn_on_first_escape = false; /* warn only once per string */ warn_on_first_escape = false; /* warn only once per string */
} }
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.269 2005/06/26 03:03:41 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.270 2005/06/26 19:16:06 tgl Exp $
* *
*-------------------------------------------------------------------- *--------------------------------------------------------------------
*/ */
...@@ -190,7 +190,6 @@ static int max_index_keys; ...@@ -190,7 +190,6 @@ static int max_index_keys;
static int max_identifier_length; static int max_identifier_length;
static int block_size; static int block_size;
static bool integer_datetimes; static bool integer_datetimes;
static bool escape_string_syntax;
static bool standard_compliant_strings; static bool standard_compliant_strings;
/* should be static, but commands/variable.c needs to get at it */ /* should be static, but commands/variable.c needs to get at it */
...@@ -877,26 +876,16 @@ static struct config_bool ConfigureNamesBool[] = ...@@ -877,26 +876,16 @@ static struct config_bool ConfigureNamesBool[] =
{ {
{"escape_string_warning", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, {"escape_string_warning", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
gettext_noop("Warn about backslash escapes in ordinary, non-escape-syntax strings."), gettext_noop("Warn about backslash escapes in ordinary string literals."),
NULL NULL
}, },
&escape_string_warning, &escape_string_warning,
false, NULL, NULL false, NULL, NULL
}, },
{
{"escape_string_syntax", PGC_INTERNAL, PRESET_OPTIONS,
gettext_noop("Escape string syntax (E'') is supported."),
NULL,
GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
},
&escape_string_syntax,
true, NULL, NULL
},
{ {
{"standard_compliant_strings", PGC_INTERNAL, PRESET_OPTIONS, {"standard_compliant_strings", PGC_INTERNAL, PRESET_OPTIONS,
gettext_noop("'' strings treat backslashes literally."), gettext_noop("'...' strings treat backslashes literally."),
NULL, NULL,
GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
}, },
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/psql/psqlscan.l,v 1.14 2005/06/02 17:45:19 tgl Exp $ * $PostgreSQL: pgsql/src/bin/psql/psqlscan.l,v 1.15 2005/06/26 19:16:06 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -235,17 +235,18 @@ quotefail {quote}{whitespace}*"-" ...@@ -235,17 +235,18 @@ quotefail {quote}{whitespace}*"-"
xbstart [bB]{quote} xbstart [bB]{quote}
xbinside [^']* xbinside [^']*
/* Hexadecimal number /* Hexadecimal number */
*/
xhstart [xX]{quote} xhstart [xX]{quote}
xhinside [^']* xhinside [^']*
/* National character /* National character */
*/
xnstart [nN]{quote} xnstart [nN]{quote}
/* Quoted string that allows backslash escapes */
xestart [eE]{quote}
/* Extended quote /* Extended quote
* xqdouble implements embedded quote * xqdouble implements embedded quote, ''''
*/ */
xqstart {quote} xqstart {quote}
xqdouble {quote}{quote} xqdouble {quote}{quote}
...@@ -450,6 +451,10 @@ other . ...@@ -450,6 +451,10 @@ other .
BEGIN(xq); BEGIN(xq);
ECHO; ECHO;
} }
{xestart} {
BEGIN(xq);
ECHO;
}
<xq>{quotestop} | <xq>{quotestop} |
<xq>{quotefail} { <xq>{quotefail} {
yyless(1); yyless(1);
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* Copyright (c) 2003-2005, PostgreSQL Global Development Group * Copyright (c) 2003-2005, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/include/utils/errcodes.h,v 1.17 2005/01/01 20:44:30 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/errcodes.h,v 1.18 2005/06/26 19:16:06 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -126,6 +126,7 @@ ...@@ -126,6 +126,7 @@
#define ERRCODE_INVALID_ESCAPE_CHARACTER MAKE_SQLSTATE('2','2', '0','1','9') #define ERRCODE_INVALID_ESCAPE_CHARACTER MAKE_SQLSTATE('2','2', '0','1','9')
#define ERRCODE_INVALID_ESCAPE_OCTET MAKE_SQLSTATE('2','2', '0','0','D') #define ERRCODE_INVALID_ESCAPE_OCTET MAKE_SQLSTATE('2','2', '0','0','D')
#define ERRCODE_INVALID_ESCAPE_SEQUENCE MAKE_SQLSTATE('2','2', '0','2','5') #define ERRCODE_INVALID_ESCAPE_SEQUENCE MAKE_SQLSTATE('2','2', '0','2','5')
#define ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER MAKE_SQLSTATE('2','2', 'P','0','6')
#define ERRCODE_INVALID_INDICATOR_PARAMETER_VALUE MAKE_SQLSTATE('2','2', '0','1','0') #define ERRCODE_INVALID_INDICATOR_PARAMETER_VALUE MAKE_SQLSTATE('2','2', '0','1','0')
#define ERRCODE_INVALID_LIMIT_VALUE MAKE_SQLSTATE('2','2', '0','2','0') #define ERRCODE_INVALID_LIMIT_VALUE MAKE_SQLSTATE('2','2', '0','2','0')
#define ERRCODE_INVALID_PARAMETER_VALUE MAKE_SQLSTATE('2','2', '0','2','3') #define ERRCODE_INVALID_PARAMETER_VALUE MAKE_SQLSTATE('2','2', '0','2','3')
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/scan.l,v 1.41 2005/06/22 01:35:02 neilc Exp $ * $PostgreSQL: pgsql/src/pl/plpgsql/src/scan.l,v 1.42 2005/06/26 19:16:07 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -291,6 +291,12 @@ dump { return O_DUMP; } ...@@ -291,6 +291,12 @@ dump { return O_DUMP; }
start_charpos = yytext; start_charpos = yytext;
BEGIN(IN_STRING); BEGIN(IN_STRING);
} }
[eE]' {
/* for now, treat the same as a regular literal */
start_lineno = plpgsql_scanner_lineno();
start_charpos = yytext;
BEGIN(IN_STRING);
}
<IN_STRING>\\. { } <IN_STRING>\\. { }
<IN_STRING>\\ { /* can only happen with \ at EOF */ } <IN_STRING>\\ { /* can only happen with \ at EOF */ }
<IN_STRING>'' { } <IN_STRING>'' { }
...@@ -563,18 +569,41 @@ plpgsql_get_string_value(void) ...@@ -563,18 +569,41 @@ plpgsql_get_string_value(void)
memcpy(result, yytext + dolqlen, len); memcpy(result, yytext + dolqlen, len);
result[len] = '\0'; result[len] = '\0';
} }
else if (*yytext == 'E' || *yytext == 'e')
{
/* Token is an E'...' string */
result = (char *) palloc(yyleng + 1); /* more than enough room */
len = 0;
for (cp = yytext + 2; *cp; cp++)
{
if (*cp == '\'')
{
if (cp[1] == '\'')
result[len++] = *cp++;
/* else it must be string end quote */
}
else if (*cp == '\\')
{
if (cp[1] != '\0') /* just a paranoid check */
result[len++] = *(++cp);
}
else
result[len++] = *cp;
}
result[len] = '\0';
}
else else
{ {
/* Token is a '...' string */ /* Token is a '...' string */
result = (char *) palloc(yyleng + 1); /* more than enough room */ result = (char *) palloc(yyleng + 1); /* more than enough room */
len = 0; len = 0;
for (cp = yytext; *cp; cp++) for (cp = yytext + 1; *cp; cp++)
{ {
if (*cp == '\'') if (*cp == '\'')
{ {
if (cp[1] == '\'') if (cp[1] == '\'')
result[len++] = *cp++; result[len++] = *cp++;
/* else it must be string start or end quote */ /* else it must be string end quote */
} }
else if (*cp == '\\') else if (*cp == '\\')
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment