Thread: psql misbehaves because of a simple typo

psql misbehaves because of a simple typo

From
"Serguei Mokhov"
Date:
Hi,

Is it me (who hasn't read some FAQ or a doc/man page) or
it's a bug in the psql interactive terminal?

A sample session is provided at the bottom. I just typed
a simple CREATE TABLE command and did not put closing
parenthesis (I was typing too fast); I did put a semicolon, however.
psql gave me no error message whatsoever and accepted whatever
input afterwards and ignored it with the exception of \commands.

Was this reported? Do you need some other info?
Logs?

o I have a RHL7.1 and the tarball of 7.2b3 downloaded from the website.

o # ./configure  --enable-nls --enable-multibyte --enable-locale --enable-debug --enable-cassert

Here is the session:

[regress72b3@gunn regress72b3]$ /usr/local/pgsql/bin/psql test
Welcome to psql, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms      \h for help with SQL commands      \? for help on internal slash commands
    \g or terminate with semicolon to execute query      \q to quit
 

test=# create table test2(id serial;
test(# select version();
test(# ?
test(# \?\a             toggle between unaligned and aligned output mode\c[onnect] [DBNAME|- [USER]]
connectto new database (currently "test")\C TITLE       set table title\cd [DIRNAME]  change the current working
directory\copy...      perform SQL COPY with data stream to the client host\copyright     show PostgreSQL usage and
distributionterms\d TABLE       describe table (or view, index, sequence)\d{t|i|s|v}... list
tables/indexes/sequences/views\d{p|S|l}     list access privileges, system tables, or large objects\da            list
aggregatefunctions\dd NAME       show comment for table, type, function, or operator\df            list functions\do
       list operators\dT            list data types\e FILENAME    edit the current query buffer or file with external
editor\echoTEXT     write text to standard output\encoding ENCODING  set client encoding\f STRING      set field
separator\gFILENAME    send SQL command to server (and write results to file or |pipe)\h NAME        help on syntax of
SQLcommands, * for all commands\H             toggle HTML output mode (currently off)\i FILENAME    execute commands
fromfile\l             list all databases\lo_export, \lo_import, \lo_list, \lo_unlink               large object
operations\oFILENAME    send all query results to file or |pipe\p             show the content of the current query
buffer\psetVAR      set table output option (VAR := {format|border|expanded|
fieldsep|null|recordsep|tuples_only|title|tableattr|pager})\q            quit psql\qecho TEXT    write text to query
outputstream (see \o)\r             reset (clear) the query buffer\s FILENAME    print history or save it to file\set
NAMEVALUE  set internal variable\t             show only rows (currently off)\T TEXT        set HTML table tag
attributes\unsetNAME    unset (delete) internal variable\w FILENAME    write current query buffer to file\x
toggleexpanded output (currently off)\z             list table access privileges\! [COMMAND]   execute command in shell
orstart interactive shell
 
test-# select version();
ERROR:  parser: parse error at or near ";"
test=# select version();                          version
-------------------------------------------------------------PostgreSQL 7.2b3 on i686-pc-linux-gnu, compiled by GCC
2.96
(1 row)
test=#

--
Serguei A. Mokhov 



Re: psql misbehaves because of a simple typo

From
Tom Lane
Date:
"Serguei Mokhov" <sa_mokho@alcor.concordia.ca> writes:
> Is it me (who hasn't read some FAQ or a doc/man page) or
> it's a bug in the psql interactive terminal?

Both.  There's a bug there, but it's not the one you think.
psql seems to forget that it's got unmatched parentheses in the
buffer after executing a \? command.  Watch the prompt:

regression=# (select
regression(# \?... yadda yadda ...
regression-# 2;
ERROR:  parser: parse error at or near ";"
regression=# (select
regression(# \?... yadda yadda ...
regression-# 2);?column?
----------       2
(1 row)

In the first example, it should not have thought that it had
a complete command after "2;".
        regards, tom lane


Re: psql misbehaves because of a simple typo

From
"Serguei Mokhov"
Date:
----- Original Message ----- 
From: Tom Lane <tgl@sss.pgh.pa.us>
Sent: Sunday, December 02, 2001 10:16 AM

> "Serguei Mokhov" <sa_mokho@alcor.concordia.ca> writes:
> > Is it me (who hasn't read some FAQ or a doc/man page) or
> > it's a bug in the psql interactive terminal?
> 
> Both. 

Oops.

> There's a bug there, but it's not the one you think.

No, that's what I thought.

> psql seems to forget that it's got unmatched parentheses in the
> buffer after executing a \? command.  Watch the prompt:

... and that's what I've witnessed.

Sorry for the 'false' alarm. This feature just bumped
into me unexpectedly.

-s



Re: psql misbehaves because of a simple typo

From
Bruce Momjian
Date:
> "Serguei Mokhov" <sa_mokho@alcor.concordia.ca> writes:
> > Is it me (who hasn't read some FAQ or a doc/man page) or
> > it's a bug in the psql interactive terminal?
> 
> Both.  There's a bug there, but it's not the one you think.
> psql seems to forget that it's got unmatched parentheses in the
> buffer after executing a \? command.  Watch the prompt:
> 
> regression=# (select
> regression(# \?
>  ... yadda yadda ...
> regression-# 2;
> ERROR:  parser: parse error at or near ";"
> regression=# (select
> regression(# \?
>  ... yadda yadda ...
> regression-# 2);
>  ?column?
> ----------
>         2
> (1 row)
> 
> In the first example, it should not have thought that it had
> a complete command after "2;".

The actual code that resets the paren level is:
/* backslash command */else if (was_bslash){    const char *end_of_cmd = NULL;
    paren_level = 0;    line[i - prevlen] = '\0'; /* overwrites backslash */

I believe this code is good.  If someone issues a backslash command,
they probably want to get out of they paren nesting, or may not even
know they are in paren nesting, as Serguei did not in the example shown.

While it doesn't seem logical, it does help prevent people from getting
stuck in psql.  The fact that backslash commands inside parens clear the
counter is a minor anoyance but resonable behavior.

--  Bruce Momjian                        |  http://candle.pha.pa.us 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,
Pennsylvania19026
 


Re: psql misbehaves because of a simple typo

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> The fact that backslash commands inside parens clear the
> counter is a minor anoyance but resonable behavior.

If they cleared the command buffer too, it might be construed
as novice-friendly behavior (though I'd still call it broken).
However, letting the counter get out of sync with the buffer
contents cannot be called anything but a bug.
        regards, tom lane


Re: psql misbehaves because of a simple typo

From
Bruce Momjian
Date:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > The fact that backslash commands inside parens clear the
> > counter is a minor anoyance but resonable behavior.
> 
> If they cleared the command buffer too, it might be construed
> as novice-friendly behavior (though I'd still call it broken).
> However, letting the counter get out of sync with the buffer
> contents cannot be called anything but a bug.

Maybe we should clear the counter _only_ if the user clears the buffer,
or sends the query to the backend with \g.

--  Bruce Momjian                        |  http://candle.pha.pa.us 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,
Pennsylvania19026
 


Re: psql misbehaves because of a simple typo

From
Bruce Momjian
Date:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > The fact that backslash commands inside parens clear the
> > counter is a minor anoyance but resonable behavior.
> 
> If they cleared the command buffer too, it might be construed
> as novice-friendly behavior (though I'd still call it broken).
> However, letting the counter get out of sync with the buffer
> contents cannot be called anything but a bug.

OK, so what do we want to do?  Clearing the buffer on a any backslash
command is clearly not what we want to do.  Should we clear the buffer
on a backslash command _only_ if the number of paren's is not even?  If
we don't clear the counter on a backslash command with uneven parens, do
we risk trapping people in psql?

--  Bruce Momjian                        |  http://candle.pha.pa.us 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,
Pennsylvania19026
 


Re: psql misbehaves because of a simple typo

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> OK, so what do we want to do?  Clearing the buffer on a any backslash
> command is clearly not what we want to do.  Should we clear the buffer
> on a backslash command _only_ if the number of paren's is not even?  If
> we don't clear the counter on a backslash command with uneven parens, do
> we risk trapping people in psql?

"Trap"?  AFAIK \q works in any case.

\r should reset both the buffer and the counter, and seems to do so,
though I'm not quite seeing where it manages to accomplish the latter
(command.c only resets query_buf).  \e should probably provoke a
recomputation of paren_level after the edit occurs.  Offhand I do not
think that any other backslash commands should reset either the buffer
or the counter.  Peter, your thoughts?
        regards, tom lane


Re: psql misbehaves because of a simple typo

From
Bruce Momjian
Date:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > OK, so what do we want to do?  Clearing the buffer on a any backslash
> > command is clearly not what we want to do.  Should we clear the buffer
> > on a backslash command _only_ if the number of paren's is not even?  If
> > we don't clear the counter on a backslash command with uneven parens, do
> > we risk trapping people in psql?
> 
> "Trap"?  AFAIK \q works in any case.
> 
> \r should reset both the buffer and the counter, and seems to do so,
> though I'm not quite seeing where it manages to accomplish the latter
> (command.c only resets query_buf).  \e should probably provoke a

See mainloop.c, line 450.  Any backshash command resets the counter.

> recomputation of paren_level after the edit occurs.  Offhand I do not
> think that any other backslash commands should reset either the buffer
> or the counter.  Peter, your thoughts?

Re-doing it for the editor is interesting.  The other items like quotes
and stuff should also probably be recomputed too.

--  Bruce Momjian                        |  http://candle.pha.pa.us 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,
Pennsylvania19026
 


Re: psql misbehaves because of a simple typo

From
Bruce Momjian
Date:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > OK, so what do we want to do?  Clearing the buffer on a any backslash
> > command is clearly not what we want to do.  Should we clear the buffer
> > on a backslash command _only_ if the number of paren's is not even?  If
> > we don't clear the counter on a backslash command with uneven parens, do
> > we risk trapping people in psql?
>
> "Trap"?  AFAIK \q works in any case.
>
> \r should reset both the buffer and the counter, and seems to do so,
> though I'm not quite seeing where it manages to accomplish the latter
> (command.c only resets query_buf).  \e should probably provoke a
> recomputation of paren_level after the edit occurs.  Offhand I do not
> think that any other backslash commands should reset either the buffer
> or the counter.  Peter, your thoughts?

OK, here is a patch for 7.3.  It clears the paren counter only when the
buffer is cleared.  Forget what I said about recomputing quotes.  You
can't use backslash commands while you are in quotes.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  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
Index: src/bin/psql/mainloop.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/mainloop.c,v
retrieving revision 1.43
diff -c -r1.43 mainloop.c
*** src/bin/psql/mainloop.c    2001/11/05 17:46:31    1.43
--- src/bin/psql/mainloop.c    2001/12/28 04:41:48
***************
*** 447,453 ****
              {
                  const char *end_of_cmd = NULL;

-                 paren_level = 0;
                  line[i - prevlen] = '\0';        /* overwrites backslash */

                  /* is there anything else on the line for the command? */
--- 447,452 ----
***************
*** 469,474 ****
--- 468,476 ----
                                                   &end_of_cmd);

                  success = slashCmdStatus != CMD_ERROR;
+
+                 if (query_buf->len == 0)
+                     paren_level = 0;

                  if ((slashCmdStatus == CMD_SEND || slashCmdStatus == CMD_NEWEDIT) &&
                      query_buf->len == 0)

Re: psql misbehaves because of a simple typo

From
Bruce Momjian
Date:
> 
> --- Bruce Momjian <pgman@candle.pha.pa.us> wrote:
> 
> [...]
> > See mainloop.c, line 450.  Any backshash command resets the counter.
> > 
> > > recomputation of paren_level after the edit occurs.  Offhand I do not
> > > think that any other backslash commands should reset either the buffer
> > > or the counter.  Peter, your thoughts?
> > 
> > Re-doing it for the editor is interesting.  The other items like quotes
> > and stuff should also probably be recomputed too.
> 
> Whooof! Looks like psql's sitting on a quite big can of worms.
> You don't plan to take them all out before 7.2, do you?

No, this is all 7.3 discussion.

--  Bruce Momjian                        |  http://candle.pha.pa.us 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,
Pennsylvania19026
 


Re: psql misbehaves because of a simple typo

From
Peter Eisentraut
Date:
Bruce Momjian writes:

> OK, here is a patch for 7.3.  It clears the paren counter only when the
> buffer is cleared.  Forget what I said about recomputing quotes.  You
> can't use backslash commands while you are in quotes.

I don't think this works when the command is \g because you're testing for
the cleared buffer too early.  Look at what happens under "if
(slashCmdStatus == CMD_SEND)".  The test should be after that (around line
489 in original copy).

-- 
Peter Eisentraut   peter_e@gmx.net



Re: psql misbehaves because of a simple typo

From
Bruce Momjian
Date:
> Bruce Momjian writes:
>
> > OK, here is a patch for 7.3.  It clears the paren counter only when the
> > buffer is cleared.  Forget what I said about recomputing quotes.  You
> > can't use backslash commands while you are in quotes.
>
> I don't think this works when the command is \g because you're testing for
> the cleared buffer too early.  Look at what happens under "if
> (slashCmdStatus == CMD_SEND)".  The test should be after that (around line
> 489 in original copy).

Are you sure?

    test=> (select
    test(> \g
    ERROR:  parser: parse error at or near ""
    test(>


I now see the next \p kills me:

    test(> \p
    ( select
    test=>

Oops, line 489 doesn't work either:

    test=> (select
    test(> \g
    ERROR:  parser: parse error at or near ""
    test=>

I now remember how confusing the previous_buffer handling is.  It is
this line that is tricky:

    /* handle backslash command */
    slashCmdStatus = HandleSlashCmds(&line[i],
           query_buf->len > 0 ? query_buf : previous_buf,
                                        ^^^^^^^^^^^^^^^^^^^^^^^^
                                        &end_of_cmd);
It works now:

    test=> (select
    test(> \g
    ERROR:  parser: parse error at or near ""
    test(> \p
    (select

Patch attached.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  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
Index: src/bin/psql/mainloop.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/mainloop.c,v
retrieving revision 1.45
diff -c -r1.45 mainloop.c
*** src/bin/psql/mainloop.c    2001/12/28 05:01:05    1.45
--- src/bin/psql/mainloop.c    2001/12/28 19:12:37
***************
*** 447,453 ****
              {
                  const char *end_of_cmd = NULL;

-                 paren_level = 0;
                  line[i - prevlen] = '\0';        /* overwrites backslash */

                  /* is there anything else on the line for the command? */
--- 447,452 ----
***************
*** 473,479 ****
                  if ((slashCmdStatus == CMD_SEND || slashCmdStatus == CMD_NEWEDIT) &&
                      query_buf->len == 0)
                  {
!                     /* copy previous buffer to current for for handling */
                      appendPQExpBufferStr(query_buf, previous_buf->data);
                  }

--- 472,478 ----
                  if ((slashCmdStatus == CMD_SEND || slashCmdStatus == CMD_NEWEDIT) &&
                      query_buf->len == 0)
                  {
!                     /* copy previous buffer to current for handling */
                      appendPQExpBufferStr(query_buf, previous_buf->data);
                  }

***************
*** 486,491 ****
--- 485,493 ----
                      appendPQExpBufferStr(previous_buf, query_buf->data);
                      resetPQExpBuffer(query_buf);
                  }
+
+                 if (query_buf->len == 0 && previous_buf->len == 0)
+                     paren_level = 0;

                  /* process anything left after the backslash command */
                  i += end_of_cmd - &line[i];

Re: psql misbehaves because of a simple typo

From
Serguei Mokhov
Date:
--- Bruce Momjian <pgman@candle.pha.pa.us> wrote:

[...]
> See mainloop.c, line 450.  Any backshash command resets the counter.
> 
> > recomputation of paren_level after the edit occurs.  Offhand I do not
> > think that any other backslash commands should reset either the buffer
> > or the counter.  Peter, your thoughts?
> 
> Re-doing it for the editor is interesting.  The other items like quotes
> and stuff should also probably be recomputed too.

Whooof! Looks like psql's sitting on a quite big can of worms.
You don't plan to take them all out before 7.2, do you?



=====
--
Serguei A. Mokhov <mailto:mokhov@cs.concordia.ca>

__________________________________________________
Do You Yahoo!?
Send your FREE holiday greetings online!
http://greetings.yahoo.com