]> granicus.if.org Git - postgresql/commitdiff
Tweak libpq so that if a backend ERROR message arrives while libpq
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 24 Feb 2000 04:50:51 +0000 (04:50 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 24 Feb 2000 04:50:51 +0000 (04:50 +0000)
thinks the connection is idle, the error message is displayed as if
it were a NOTICE.  This seems better than dropping the message on
the floor ... particularly if the message is the backend telling us
why it's about to close the connection.  The previous behavior was
Backend message type 0x45 arrived while idle
pqReadData() -- backend closed the channel unexpectedly.
which is not real helpful.

src/interfaces/libpq/fe-exec.c

index 8bba82e788ef224f02850a7ed3c43c390ce67ae5..7be05bd525a0c68b2ac1be0d8ed8de9e1cbb2ed2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.90 2000/02/07 23:10:10 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.91 2000/02/24 04:50:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -669,6 +669,13 @@ parseInput(PGconn *conn)
                /*
                 * NOTIFY and NOTICE messages can happen in any state besides COPY
                 * OUT; always process them right away.
+                *
+                * Most other messages should only be processed while in BUSY state.
+                * (In particular, in READY state we hold off further parsing until
+                * the application collects the current PGresult.)
+                *
+                * However, if the state is IDLE then we got trouble; we need to
+                * deal with the unexpected message somehow.
                 */
                if (id == 'A')
                {
@@ -680,28 +687,40 @@ parseInput(PGconn *conn)
                        if (getNotice(conn))
                                return;
                }
-               else
+               else if (conn->asyncStatus != PGASYNC_BUSY)
                {
-
+                       /* If not IDLE state, just wait ... */
+                       if (conn->asyncStatus != PGASYNC_IDLE)
+                               return;
                        /*
-                        * Other messages should only be processed while in BUSY
-                        * state. (In particular, in READY state we hold off further
-                        * parsing until the application collects the current
-                        * PGresult.) If the state is IDLE then we got trouble.
+                        * Unexpected message in IDLE state; need to recover somehow.
+                        * ERROR messages are displayed using the notice processor;
+                        * anything else is just dropped on the floor after displaying
+                        * a suitable warning notice.  (An ERROR is very possibly the
+                        * backend telling us why it is about to close the connection,
+                        * so we don't want to just discard it...)
                         */
-                       if (conn->asyncStatus != PGASYNC_BUSY)
+                       if (id == 'E')
                        {
-                               if (conn->asyncStatus == PGASYNC_IDLE)
-                               {
-                                       sprintf(noticeWorkspace,
-                                                       "Backend message type 0x%02x arrived while idle\n",
-                                                       id);
-                                       DONOTICE(conn, noticeWorkspace);
-                                       /* Discard the unexpected message; good idea?? */
-                                       conn->inStart = conn->inEnd;
-                               }
-                               return;
+                               if (getNotice(conn))
+                                       return;
+                       }
+                       else
+                       {
+                               sprintf(noticeWorkspace,
+                                               "Backend message type 0x%02x arrived while idle\n",
+                                               id);
+                               DONOTICE(conn, noticeWorkspace);
+                               /* Discard the unexpected message; good idea?? */
+                               conn->inStart = conn->inEnd;
+                               break;
                        }
+               }
+               else
+               {
+                       /*
+                        * In BUSY state, we can process everything.
+                        */
                        switch (id)
                        {
                                case 'C':               /* command complete */