OSDN Git Service

Hi,
authorBruce Momjian <bruce@momjian.us>
Sun, 14 Mar 1999 16:42:15 +0000 (16:42 +0000)
committerBruce Momjian <bruce@momjian.us>
Sun, 14 Mar 1999 16:42:15 +0000 (16:42 +0000)
    Just in case you'd like to see what I was talking about, I am
attaching
my patch to src/interfaces/libpq/fe-exec.c to prevent utility functions
called from SPI from locking up the client.

Jerry Gay

src/interfaces/libpq/fe-exec.c

index 4f40801..34f6d62 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.74 1999/02/13 23:22:41 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.75 1999/03/14 16:42:15 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -467,6 +467,7 @@ static void
 parseInput(PGconn *conn)
 {
        char            id;
+        static int      pendingT = 0;
 
        /*
         * Loop to parse successive complete messages available in the buffer.
@@ -535,7 +536,15 @@ parseInput(PGconn *conn)
                                                                                                                   PGRES_COMMAND_OK);
                                        if (pqGets(conn->result->cmdStatus, CMDSTATUS_LEN, conn))
                                                return;
-                                       conn->asyncStatus = PGASYNC_READY;
+                                        if (pendingT) {
+                                            /* Check the returned message */
+                                            /* if it's a SELECT in a pendingT case, */
+                                            /* then it probably means no rows returned. */
+                                            /* We clear pendingT in that case. */
+                                            if (strncmp(conn->result->cmdStatus, "SELECT", 6) == 0)
+                                                pendingT = 0;
+                                        }
+                                       if (!pendingT) conn->asyncStatus = PGASYNC_READY;
                                        break;
                                case 'E':               /* error return */
                                        if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, conn))
@@ -545,10 +554,11 @@ parseInput(PGconn *conn)
                                        /* and build an error result holding the error message */
                                        conn->result = PQmakeEmptyPGresult(conn,
                                                                                                           PGRES_FATAL_ERROR);
-                                       conn->asyncStatus = PGASYNC_READY;
+                                       if (!pendingT) conn->asyncStatus = PGASYNC_READY;
                                        break;
                                case 'Z':               /* backend is ready for new query */
                                        conn->asyncStatus = PGASYNC_IDLE;
+                                        pendingT = 0;
                                        break;
                                case 'I':               /* empty query */
                                        /* read and throw away the closing '\0' */
@@ -563,7 +573,7 @@ parseInput(PGconn *conn)
                                        if (conn->result == NULL)
                                                conn->result = PQmakeEmptyPGresult(conn,
                                                                                                                   PGRES_EMPTY_QUERY);
-                                       conn->asyncStatus = PGASYNC_READY;
+                                       if (!pendingT) conn->asyncStatus = PGASYNC_READY;
                                        break;
                                case 'K':               /* secret key data from the backend */
 
@@ -584,11 +594,15 @@ parseInput(PGconn *conn)
                                        break;
                                case 'T':               /* row descriptions (start of query
                                                                 * results) */
+                                        if (pendingT) {
+                                            DONOTICE(conn, "Got second 'T' message!\n");
+                                        }
                                        if (conn->result == NULL)
                                        {
                                                /* First 'T' in a query sequence */
                                                if (getRowDescriptions(conn))
                                                        return;
+                                                pendingT = 1;
                                        }
                                        else
                                        {
@@ -600,11 +614,13 @@ parseInput(PGconn *conn)
                                                 * We stop parsing until the application accepts
                                                 * the current result.
                                                 */
+                                                pendingT = 0;
                                                conn->asyncStatus = PGASYNC_READY;
                                                return;
                                        }
                                        break;
                                case 'D':               /* ASCII data tuple */
+                                        pendingT = 0;
                                        if (conn->result != NULL)
                                        {
                                                /* Read another tuple of a normal query response */
@@ -622,6 +638,7 @@ parseInput(PGconn *conn)
                                        }
                                        break;
                                case 'B':               /* Binary data tuple */
+                                        pendingT = 0;
                                        if (conn->result != NULL)
                                        {
                                                /* Read another tuple of a normal query response */
@@ -639,12 +656,15 @@ parseInput(PGconn *conn)
                                        }
                                        break;
                                case 'G':               /* Start Copy In */
+                                        pendingT = 0;
                                        conn->asyncStatus = PGASYNC_COPY_IN;
                                        break;
                                case 'H':               /* Start Copy Out */
+                                        pendingT = 0;
                                        conn->asyncStatus = PGASYNC_COPY_OUT;
                                        break;
                                default:
+                                        pendingT = 0;
                                        sprintf(conn->errorMessage,
                                        "unknown protocol character '%c' read from backend.  "
                                        "(The protocol character is the first character the "