Attached is a proof-of-concept diff that makes the main SQL parser
accept quoted strings in the style recently discussed ($Q$ ... $Q$).
To complete the feature, we'd need to make the plpgsql parser do the
same, update psql to understand this, update pg_dump to use this style
of quoting for function bodies (and perhaps other things?), and update
the documentation.  The last is a nontrivial project all by itself.
Anybody want to run with this football?

                        regards, tom lane


*** src/backend/parser/scan.l.orig      Sun Aug  3 23:00:44 2003
--- src/backend/parser/scan.l   Sun Sep 14 01:38:55 2003
***************
*** 39,44 ****
--- 39,46 ----
  
  static int            xcdepth = 0;    /* depth of nesting in slash-star comments */
  
+ static char      *hqstart;            /* current here-document start string */
+ 
  /*
   * literalbuf is used to accumulate literal values when multiple rules
   * are needed to parse a single literal.  Call startlit to reset buffer
***************
*** 95,100 ****
--- 97,103 ----
   *  <xd> delimited identifiers (double-quoted identifiers)
   *  <xh> hexadecimal numeric string
   *  <xq> quoted strings
+  *  <hq> here-document-style quoted strings
   */
  
  %x xb
***************
*** 102,107 ****
--- 105,111 ----
  %x xd
  %x xh
  %x xq
+ %x hq
  
  /* Bit string
   * It is tempting to scan the string for only those characters
***************
*** 141,146 ****
--- 145,157 ----
  xqoctesc              [\\][0-7]{1,3}
  xqcat                 {quote}{whitespace_with_newline}{quote}
  
+ /* Here-document-style quotes
+  * The quoted string starts with $letters$ and extends to the first occurrence
+  * of an identical string.  There is *no* processing of the quoted text.
+  */
+ hqdelim                       \$[A-Za-z]*\$
+ hqinside              [^$]+
+ 
  /* Double quote
   * Allows embedded spaces and other special characters into identifiers.
   */
***************
*** 387,392 ****
--- 398,432 ----
                                }
  <xq><<EOF>>           { yyerror("unterminated quoted string"); }
  
+ {hqdelim}             {
+                                       token_start = yytext;
+                                       hqstart = pstrdup(yytext);
+                                       BEGIN(hq);
+                                       startlit();
+                               }
+ <hq>{hqdelim} {
+                                       if (strcmp(yytext, hqstart) == 0)
+                                       {
+                                               pfree(hqstart);
+                                               BEGIN(INITIAL);
+                                               yylval.str = litbufdup();
+                                               return SCONST;
+                                       }
+                                       /*
+                                        * When we fail to match $...$ to hqstart, 
transfer
+                                        * the $... part to the output, but put back 
the final
+                                        * $ for rescanning.  Consider 
$delim$...$junk$delim$
+                                        */
+                                       addlit(yytext, yyleng-1);
+                                       yyless(yyleng-1);
+                               }
+ <hq>{hqinside}  {
+                                       addlit(yytext, yyleng);
+                               }
+ <hq>.           {
+                                       addlitchar(yytext[0]);
+                               }
+ <hq><<EOF>>           { yyerror("unterminated special-quoted string"); }
  
  {xdstart}             {
                                        token_start = yytext;

---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

               http://www.postgresql.org/docs/faqs/FAQ.html

Reply via email to