Tom Lane wrote:
I think plpgsql's lexer also needs to be taught about dollar-quoting.
The attached patch appears to do the trick:
floobl=# create or replace function testme() returns text language
plpgsql as $$
floobl$# begin return $foo$a'\b$bar$foo$; end;
floobl$# $$;
CREATE FUNCTION
floobl=# select testme();
testme
--
a'\b$bar
(1 row)
floobl=#
cheers
andrew
Index: src/pl/plpgsql/src/scan.l
===
RCS file: /projects/cvsroot/pgsql-server/src/pl/plpgsql/src/scan.l,v
retrieving revision 1.31
diff -c -r1.31 scan.l
*** src/pl/plpgsql/src/scan.l 24 Feb 2004 22:06:32 - 1.31
--- src/pl/plpgsql/src/scan.l 25 Feb 2004 16:32:28 -
***
*** 57,62
--- 57,63
static bool have_lookahead_token;
static const char *cur_line_start;
static intcur_line_num;
+ static char*dolqstart; /* current $foo$ quote start string */
int plpgsql_SpaceScanned = 0;
%}
***
*** 70,76
%option case-insensitive
! %xIN_STRING IN_COMMENT
digit [0-9]
ident_start [A-Za-z\200-\377_]
--- 71,77
%option case-insensitive
! %xIN_STRING IN_COMMENT IN_DOLLARQUOTE
digit [0-9]
ident_start [A-Za-z\200-\377_]
***
*** 84,89
--- 85,98
space [ \t\n\r\f]
+ /* $foo$ style quotes (dollar quoting)
+ * copied stright from the backend SQL parser
+ */
+ dolq_start[A-Za-z\200-\377_]
+ dolq_cont [A-Za-z\200-\377_0-9]
+ dolqdelim \$({dolq_start}{dolq_cont}*)?\$
+ dolqinside[^$]+
+
%%
/* --
* Local variables in scanner to remember where
***
*** 288,293
--- 297,336
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg(unterminated string)));
}
+
+ {dolqdelim} {
+ start_lineno = plpgsql_scanner_lineno();
+ start_charpos = yytext;
+ dolqstart = pstrdup(yytext);
+ BEGIN(IN_DOLLARQUOTE);
+ }
+ IN_DOLLARQUOTE{dolqdelim} {
+ if (strcmp(yytext, dolqstart) == 0)
+ {
+ pfree(dolqstart);
+ yyleng -= (yytext - start_charpos);
+ yytext = start_charpos;
+ BEGIN INITIAL;
+ return T_STRING;
+ }
+ else
+ {
+ /*
+* When we fail to match $...$ to
dolqstart, transfer
+* the $... part to the output, but
put back the final
+* $ for rescanning. Consider
$delim$...$junk$delim$
+*/
+ yyless(yyleng-1);
+ }
+ }
+ IN_DOLLARQUOTE{dolqinside} { }
+ IN_DOLLARQUOTE. { /* needed for $ inside the quoted text */ }
+ IN_DOLLARQUOTEEOF {
+ plpgsql_error_lineno = start_lineno;
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+errmsg(unterminated dollar quoted
string)));
+ }
/* --
* Any unmatched character is returned as is
---(end of broadcast)---
TIP 2: you can get off all lists at once with the unregister command
(send unregister YourEmailAddressHere to [EMAIL PROTECTED])