diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7d0eb39f96cbe22cb638b0a9a24053ea91cf5379..df43f2cad2bc7c3738841e7a8513535d18264df0 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.135 2003/05/08 18:16:37 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.136 2003/05/26 20:05:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -55,7 +55,7 @@ static void parseInput(PGconn *conn);
 static void handleSendFailure(PGconn *conn);
 static void handleSyncLoss(PGconn *conn, char id, int msgLength);
 static int	getRowDescriptions(PGconn *conn);
-static int	getAnotherTuple(PGconn *conn);
+static int	getAnotherTuple(PGconn *conn, int msgLength);
 static int	getParameterStatus(PGconn *conn);
 static int	getNotify(PGconn *conn);
 
@@ -835,17 +835,28 @@ parseInput(PGconn *conn)
 					}
 					break;
 				case 'D':		/* Data Row */
-					if (conn->result != NULL)
+					if (conn->result != NULL &&
+						conn->result->resultStatus == PGRES_TUPLES_OK)
 					{
 						/* Read another tuple of a normal query response */
-						if (getAnotherTuple(conn))
+						if (getAnotherTuple(conn, msgLength))
 							return;
 					}
+					else if (conn->result != NULL &&
+							 conn->result->resultStatus == PGRES_FATAL_ERROR)
+					{
+						/*
+						 * We've already choked for some reason.  Just discard
+						 * tuples till we get to the end of the query.
+						 */
+						conn->inCursor += msgLength;
+					}
 					else
 					{
-						snprintf(noticeWorkspace, sizeof(noticeWorkspace),
+						/* Set up to report error at end of query */
+						printfPQExpBuffer(&conn->errorMessage,
 								 libpq_gettext("server sent data (\"D\" message) without prior row description (\"T\" message)\n"));
-						DONOTICE(conn, noticeWorkspace);
+						saveErrorResult(conn);
 						/* Discard the unexpected message */
 						conn->inCursor += msgLength;
 					}
@@ -888,6 +899,7 @@ parseInput(PGconn *conn)
 									  id);
 					/* build an error result holding the error message */
 					saveErrorResult(conn);
+					/* not sure if we will see more, so go to ready state */
 					conn->asyncStatus = PGASYNC_READY;
 					/* Discard the unexpected message */
 					conn->inCursor += msgLength;
@@ -931,6 +943,7 @@ handleSyncLoss(PGconn *conn, char id, int msgLength)
 	pqsecure_close(conn);
 	closesocket(conn->sock);
 	conn->sock = -1;
+	conn->asyncStatus = PGASYNC_READY; /* drop out of GetResult wait loop */
 }
 
 /*
@@ -1023,7 +1036,7 @@ getRowDescriptions(PGconn *conn)
  */
 
 static int
-getAnotherTuple(PGconn *conn)
+getAnotherTuple(PGconn *conn, int msgLength)
 {
 	PGresult   *result = conn->result;
 	int			nfields = result->numAttributes;
@@ -1050,12 +1063,11 @@ getAnotherTuple(PGconn *conn)
 	if (tupnfields != nfields)
 	{
 		/* Replace partially constructed result with an error result */
-		pqClearAsyncResult(conn);
 		printfPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("unexpected field count in D message\n"));
 		saveErrorResult(conn);
-		conn->asyncStatus = PGASYNC_READY;
 		/* Discard the failed message by pretending we read it */
+		conn->inCursor = conn->inStart + 5 + msgLength;
 		return 0;
 	}
 
@@ -1102,14 +1114,15 @@ outOfMemory:
 
 	/*
 	 * we do NOT use saveErrorResult() here, because of the likelihood
-	 * that there's not enough memory to concatenate messages...
+	 * that there's not enough memory to concatenate messages.  Instead,
+	 * discard the old result first to try to win back some memory.
 	 */
 	pqClearAsyncResult(conn);
 	printfPQExpBuffer(&conn->errorMessage,
-					  libpq_gettext("out of memory\n"));
+					  libpq_gettext("out of memory for query result\n"));
 	conn->result = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
-	conn->asyncStatus = PGASYNC_READY;
 	/* Discard the failed message by pretending we read it */
+	conn->inCursor = conn->inStart + 5 + msgLength;
 	return 0;
 }