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 -0000 1.31 --- src/pl/plpgsql/src/scan.l 25 Feb 2004 16:32:28 -0000 *************** *** 57,62 **** --- 57,63 ---- static bool have_lookahead_token; static const char *cur_line_start; static int cur_line_num; + static char *dolqstart; /* current $foo$ quote start string */ int plpgsql_SpaceScanned = 0; %} *************** *** 70,76 **** %option case-insensitive ! %x IN_STRING IN_COMMENT digit [0-9] ident_start [A-Za-z\200-\377_] --- 71,77 ---- %option case-insensitive ! %x IN_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_DOLLARQUOTE><<EOF>> { + 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])