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); + } + {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); + } + } + {dolqinside} { } + . { /* needed for $ inside the quoted text */ } + <> { + plpgsql_error_lineno = start_lineno; + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("unterminated dollar quoted string"))); + } /* ---------- * Any unmatched character is returned as is