Re: Comments with embedded single quotes - Mailing list pgsql-general

From Bruce Momjian
Subject Re: Comments with embedded single quotes
Date
Msg-id 200006291627.MAA05841@candle.pha.pa.us
Whole thread Raw
In response to Re: Comments with embedded single quotes  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Comments with embedded single quotes  (Peter Eisentraut <peter_e@gmx.net>)
List pgsql-general
> Richard Harvey Chapman <hchapman@3gfp.com> writes:
> > Are single quotation marks not allowed in comments?
>
> > test2=# /* John's cat is fat. */
> > test2'#
> > test2'# '*/
> > test2-# ;
> > ERROR:  Unterminated quoted string
> > test2=#
>
> They are, but it looks like psql's primitive parser is confused here.
> What the backend sees when this is sent is
>     /* comment */
>
>     '*/
>
> and it quite properly complains that the string starting '*/ is not
> terminated.  But it looks like psql mistakenly thinks that ' nests
> inside /* ... */:
>
> regression=# /*aaa
> regression*# 'sss
> regression'# ddd
> regression'# */
> regression'# 'sss
> regression*# */
> regression-#
>
> Notice the pattern of the 'state' markers in the prompts.  It seems
> to get the reverse case correct though:
>
> regression-# 'foo
> regression'# /*bar
> regression'# '
> regression-#
>
> Over to you, Peter...

OK, here is the patch.  The problem was that quotes were being checked
before checking if we were in a comment.  Patch applied to current tree
only.


--
  Bruce Momjian                        |  http://www.op.net/~candle
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
? config.log
? config.cache
? config.status
? GNUmakefile
? src/GNUmakefile
? src/Makefile.global
? src/log
? src/Makefile.custom
? src/crtags
? src/backend/postgres
? src/backend/catalog/genbki.sh
? src/backend/catalog/global1.bki.source
? src/backend/catalog/global1.description
? src/backend/catalog/local1_template1.bki.source
? src/backend/catalog/local1_template1.description
? src/backend/port/Makefile
? src/backend/utils/Gen_fmgrtab.sh
? src/bin/initdb/initdb
? src/bin/initlocation/initlocation
? src/bin/ipcclean/ipcclean
? src/bin/pg_ctl/pg_ctl
? src/bin/pg_dump/Makefile
? src/bin/pg_dump/pg_dump
? src/bin/pg_id/pg_id
? src/bin/pg_passwd/pg_passwd
? src/bin/pg_version/Makefile
? src/bin/pg_version/pg_version
? src/bin/pgaccess/pgaccess
? src/bin/pgtclsh/mkMakefile.tcldefs.sh
? src/bin/pgtclsh/mkMakefile.tkdefs.sh
? src/bin/pgtclsh/pgtclsh
? src/bin/pgtclsh/Makefile.tkdefs
? src/bin/pgtclsh/Makefile.tcldefs
? src/bin/pgtclsh/pgtksh
? src/bin/psql/Makefile
? src/bin/psql/psql
? src/bin/scripts/createlang
? src/include/version.h
? src/include/config.h
? src/include/parser/parse.h
? src/include/utils/fmgroids.h
? src/interfaces/Makefile
? src/interfaces/ecpg/lib/Makefile
? src/interfaces/ecpg/lib/libecpg.so.3.1.1
? src/interfaces/ecpg/preproc/Makefile
? src/interfaces/ecpg/preproc/ecpg
? src/interfaces/libpgeasy/Makefile
? src/interfaces/libpgeasy/libpgeasy.so.2.1
? src/interfaces/libpgtcl/Makefile
? src/interfaces/libpgtcl/libpgtcl.so.2.1
? src/interfaces/libpq/Makefile
? src/interfaces/libpq/libpq.so.2.1
? src/interfaces/libpq++/Makefile
? src/interfaces/odbc/GNUmakefile
? src/interfaces/perl5/GNUmakefile
? src/interfaces/python/GNUmakefile
? src/pl/Makefile
? src/pl/plperl/GNUmakefile
? src/pl/plpgsql/src/Makefile
? src/pl/plpgsql/src/mklang.sql
? src/pl/plpgsql/src/libplpgsql.so.1.0
? src/pl/tcl/mkMakefile.tcldefs.sh
? src/pl/tcl/Makefile.tcldefs
? src/test/regress/GNUmakefile
Index: src/bin/psql/mainloop.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/psql/mainloop.c,v
retrieving revision 1.30
diff -c -r1.30 mainloop.c
*** src/bin/psql/mainloop.c    2000/05/12 16:13:44    1.30
--- src/bin/psql/mainloop.c    2000/06/29 16:27:00
***************
*** 18,26 ****

  #ifndef WIN32
  #include <setjmp.h>
-
  sigjmp_buf    main_loop_jmp;
-
  #endif


--- 18,24 ----
***************
*** 298,315 ****
                  bslash_count = 0;

          rescan:
!             /* in quote? */
!             if (in_quote)
              {
!                 /* end of quote */
!                 if (line[i] == in_quote && bslash_count % 2 == 0)
!                     in_quote = '\0';
              }

-             /* start of quote */
-             else if (!was_bslash && (line[i] == '\'' || line[i] == '"'))
-                 in_quote = line[i];
-
              /* in extended comment? */
              else if (xcomment)
              {
--- 296,308 ----
                  bslash_count = 0;

          rescan:
!             /* start of extended comment? */
!             if (line[i] == '/' && line[i + thislen] == '*')
              {
!                 xcomment = true;
!                 ADVANCE_1;
              }

              /* in extended comment? */
              else if (xcomment)
              {
***************
*** 320,338 ****
                  }
              }

-             /* start of extended comment? */
-             else if (line[i] == '/' && line[i + thislen] == '*')
-             {
-                 xcomment = true;
-                 ADVANCE_1;
-             }
-
              /* single-line comment? truncate line */
              else if (line[i] == '-' && line[i + thislen] == '-')
              {
                  line[i] = '\0'; /* remove comment */
                  break;
              }

              /* count nested parentheses */
              else if (line[i] == '(')
--- 313,337 ----
                  }
              }

              /* single-line comment? truncate line */
              else if (line[i] == '-' && line[i + thislen] == '-')
              {
                  line[i] = '\0'; /* remove comment */
                  break;
              }
+
+             /* in quote? */
+             else if (in_quote)
+             {
+                 /* end of quote */
+                 if (line[i] == in_quote && bslash_count % 2 == 0)
+                     in_quote = '\0';
+             }
+
+             /* start of quote */
+             else if (!was_bslash &&
+                      (line[i] == '\'' || line[i] == '"'))
+                 in_quote = line[i];

              /* count nested parentheses */
              else if (line[i] == '(')

pgsql-general by date:

Previous
From: Bob Parkinson
Date:
Subject: pg_dump/load quoting.
Next
From: Thomas Lockhart
Date:
Subject: Re: Importing data w/ Unix timestamp