From e2c4d41f32107b88f92a71d2c53e2ad850d93161 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Sun, 14 Mar 1999 16:42:15 +0000 Subject: [PATCH] Hi, 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 | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c index 4f40801748..34f6d62465 100644 --- a/src/interfaces/libpq/fe-exec.c +++ b/src/interfaces/libpq/fe-exec.c @@ -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 "