diff --git a/src/interfaces/libpq/fe-protocol2.c b/src/interfaces/libpq/fe-protocol2.c
index eeba7f3..7299bea 100644
--- a/src/interfaces/libpq/fe-protocol2.c
+++ b/src/interfaces/libpq/fe-protocol2.c
@@ -498,10 +498,17 @@ pqParseInput2(PGconn *conn)
 						conn->result = PQmakeEmptyPGresult(conn,
 														   PGRES_COMMAND_OK);
 						if (!conn->result)
-							return;
+						{
+							printfPQExpBuffer(&conn->errorMessage,
+											  libpq_gettext("out of memory"));
+							pqSaveErrorResult(conn);
+						}
+					}
+					if (conn->result)
+					{
+						strlcpy(conn->result->cmdStatus, conn->workBuffer.data,
+								CMDSTATUS_LEN);
 					}
-					strlcpy(conn->result->cmdStatus, conn->workBuffer.data,
-							CMDSTATUS_LEN);
 					checkXactStatus(conn, conn->workBuffer.data);
 					conn->asyncStatus = PGASYNC_READY;
 					break;
@@ -522,8 +529,16 @@ pqParseInput2(PGconn *conn)
 										 "unexpected character %c following empty query response (\"I\" message)",
 										 id);
 					if (conn->result == NULL)
+					{
 						conn->result = PQmakeEmptyPGresult(conn,
 														   PGRES_EMPTY_QUERY);
+						if (!conn->result)
+						{
+							printfPQExpBuffer(&conn->errorMessage,
+											  libpq_gettext("out of memory"));
+							pqSaveErrorResult(conn);
+						}
+					}
 					conn->asyncStatus = PGASYNC_READY;
 					break;
 				case 'K':		/* secret key data from the backend */
@@ -633,8 +648,7 @@ pqParseInput2(PGconn *conn)
 /*
  * parseInput subroutine to read a 'T' (row descriptions) message.
  * We build a PGresult structure containing the attribute data.
- * Returns: 0 if completed message, EOF if error or not enough data
- * received yet.
+ * Returns: 0 if completed message, EOF if not enough data received yet.
  *
  * Note that if we run out of data, we have to suspend and reprocess
  * the message after more data is received.  Otherwise, conn->inStart
@@ -755,6 +769,10 @@ advance_and_error:
 	conn->result = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
 	conn->asyncStatus = PGASYNC_READY;
 
+	if (result && result != conn->result)
+		PQclear(result);
+	return 0;
+
 EOFexit:
 	if (result && result != conn->result)
 		PQclear(result);
@@ -764,8 +782,7 @@ EOFexit:
 /*
  * parseInput subroutine to read a 'B' or 'D' (row data) message.
  * We fill rowbuf with column pointers and then call the row processor.
- * Returns: 0 if completed message, EOF if error or not enough data
- * received yet.
+ * Returns: 0 if completed message, EOF if not enough data received yet.
  *
  * Note that if we run out of data, we have to suspend and reprocess
  * the message after more data is received.  Otherwise, conn->inStart
@@ -965,14 +982,17 @@ pqGetErrorNotice2(PGconn *conn, bool isError)
 	 * Make a PGresult to hold the message.  We temporarily lie about the
 	 * result status, so that PQmakeEmptyPGresult doesn't uselessly copy
 	 * conn->errorMessage.
+	 *
+	 * NB: This allocation might fail, if you run out of memory. The rest of
+	 * the function handles that gracefully, and we still try to set the error
+	 * message as the connection's error message.
 	 */
 	res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
-	if (!res)
-		goto failure;
-	res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR;
-	res->errMsg = pqResultStrdup(res, workBuf.data);
-	if (!res->errMsg)
-		goto failure;
+	if (res)
+	{
+		res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR;
+		res->errMsg = pqResultStrdup(res, workBuf.data);
+	}
 
 	/*
 	 * Break the message into fields.  We can't do very much here, but we can
@@ -1024,15 +1044,22 @@ pqGetErrorNotice2(PGconn *conn, bool isError)
 		pqClearAsyncResult(conn);
 		conn->result = res;
 		resetPQExpBuffer(&conn->errorMessage);
-		appendPQExpBufferStr(&conn->errorMessage, res->errMsg);
+		if (res && !PQExpBufferDataBroken(workBuf))
+			appendPQExpBufferStr(&conn->errorMessage, res->errMsg);
+		else
+			printfPQExpBuffer(&conn->errorMessage,
+							  libpq_gettext("out of memory"));
 		if (conn->xactStatus == PQTRANS_INTRANS)
 			conn->xactStatus = PQTRANS_INERROR;
 	}
 	else
 	{
-		if (res->noticeHooks.noticeRec != NULL)
-			(*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res);
-		PQclear(res);
+		if (res)
+		{
+			if (res->noticeHooks.noticeRec != NULL)
+				(*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res);
+			PQclear(res);
+		}
 	}
 
 	termPQExpBuffer(&workBuf);
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index a847f08..1a6a2c7 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -204,10 +204,15 @@ pqParseInput3(PGconn *conn)
 						conn->result = PQmakeEmptyPGresult(conn,
 														   PGRES_COMMAND_OK);
 						if (!conn->result)
-							return;
+						{
+							printfPQExpBuffer(&conn->errorMessage,
+											  libpq_gettext("out of memory"));
+							pqSaveErrorResult(conn);
+						}
 					}
-					strlcpy(conn->result->cmdStatus, conn->workBuffer.data,
-							CMDSTATUS_LEN);
+					if (conn->result)
+						strlcpy(conn->result->cmdStatus, conn->workBuffer.data,
+								CMDSTATUS_LEN);
 					conn->asyncStatus = PGASYNC_READY;
 					break;
 				case 'E':		/* error return */
@@ -226,7 +231,11 @@ pqParseInput3(PGconn *conn)
 						conn->result = PQmakeEmptyPGresult(conn,
 														   PGRES_EMPTY_QUERY);
 						if (!conn->result)
-							return;
+						{
+							printfPQExpBuffer(&conn->errorMessage,
+											  libpq_gettext("out of memory"));
+							pqSaveErrorResult(conn);
+						}
 					}
 					conn->asyncStatus = PGASYNC_READY;
 					break;
@@ -239,7 +248,11 @@ pqParseInput3(PGconn *conn)
 							conn->result = PQmakeEmptyPGresult(conn,
 														   PGRES_COMMAND_OK);
 							if (!conn->result)
-								return;
+							{
+								printfPQExpBuffer(&conn->errorMessage,
+												  libpq_gettext("out of memory"));
+								pqSaveErrorResult(conn);
+							}
 						}
 						conn->asyncStatus = PGASYNC_READY;
 					}
@@ -306,7 +319,11 @@ pqParseInput3(PGconn *conn)
 							conn->result = PQmakeEmptyPGresult(conn,
 														   PGRES_COMMAND_OK);
 							if (!conn->result)
-								return;
+							{
+								printfPQExpBuffer(&conn->errorMessage,
+												  libpq_gettext("out of memory"));
+								pqSaveErrorResult(conn);
+							}
 						}
 						conn->asyncStatus = PGASYNC_READY;
 					}
@@ -628,7 +645,7 @@ getParamDescriptions(PGconn *conn)
 
 	result = PQmakeEmptyPGresult(conn, PGRES_COMMAND_OK);
 	if (!result)
-		goto failure;
+		goto oom_error;
 
 	/* parseInput already read the 't' label and message length. */
 	/* the next two bytes are the number of parameters */
@@ -642,7 +659,7 @@ getParamDescriptions(PGconn *conn)
 		result->paramDescs = (PGresParamDesc *)
 			pqResultAlloc(result, nparams * sizeof(PGresParamDesc), TRUE);
 		if (!result->paramDescs)
-			goto failure;
+			goto oom_error;
 		MemSet(result->paramDescs, 0, nparams * sizeof(PGresParamDesc));
 	}
 
@@ -661,8 +678,18 @@ getParamDescriptions(PGconn *conn)
 	return 0;
 
 failure:
-	PQclear(result);
+	/* could not read the whole message */
+	if (result)
+		PQclear(result);
 	return EOF;
+
+oom_error:
+	if (result)
+		PQclear(result);
+	printfPQExpBuffer(&conn->errorMessage,
+					  libpq_gettext("out of memory\n"));
+	pqSaveErrorResult(conn);
+	return 0;
 }
 
 /*
@@ -822,11 +849,14 @@ pqGetErrorNotice3(PGconn *conn, bool isError)
 	 * Make a PGresult to hold the accumulated fields.  We temporarily lie
 	 * about the result status, so that PQmakeEmptyPGresult doesn't uselessly
 	 * copy conn->errorMessage.
+	 *
+	 * NB: This allocation might fail, if you run out of memory. The rest of
+	 * the function handles that gracefully, and we still try to set the error
+	 * message as the connection's error message.
 	 */
 	res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
-	if (!res)
-		goto fail;
-	res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR;
+	if (res)
+		res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR;
 
 	/*
 	 * Read the fields and save into res.
@@ -966,20 +996,27 @@ pqGetErrorNotice3(PGconn *conn, bool isError)
 	 */
 	if (isError)
 	{
-		res->errMsg = pqResultStrdup(res, workBuf.data);
-		if (!res->errMsg)
-			goto fail;
+		if (res)
+			res->errMsg = pqResultStrdup(res, workBuf.data);
 		pqClearAsyncResult(conn);
 		conn->result = res;
-		appendPQExpBufferStr(&conn->errorMessage, workBuf.data);
+		if (PQExpBufferDataBroken(workBuf))
+			printfPQExpBuffer(&conn->errorMessage,
+							  libpq_gettext("out of memory"));
+		else
+			appendPQExpBufferStr(&conn->errorMessage, workBuf.data);
 	}
 	else
 	{
-		/* We can cheat a little here and not copy the message. */
-		res->errMsg = workBuf.data;
-		if (res->noticeHooks.noticeRec != NULL)
-			(*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res);
-		PQclear(res);
+		/* if we couldn't allocate the result set, just discard the NOTICE */
+		if (res)
+		{
+			/* We can cheat a little here and not copy the message. */
+			res->errMsg = workBuf.data;
+			if (res->noticeHooks.noticeRec != NULL)
+				(*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res);
+			PQclear(res);
+		}
 	}
 
 	termPQExpBuffer(&workBuf);
@@ -1309,6 +1346,7 @@ getNotify(PGconn *conn)
  * CopyBothResponse message
  *
  * parseInput already read the message type and length.
+ * Returns 0 if successfully consumed the message, EOF if not enough data.
  */
 static int
 getCopyStart(PGconn *conn, ExecStatusType copytype)
@@ -1319,7 +1357,7 @@ getCopyStart(PGconn *conn, ExecStatusType copytype)
 
 	result = PQmakeEmptyPGresult(conn, copytype);
 	if (!result)
-		goto failure;
+		goto oom_error;
 
 	if (pqGetc(&conn->copy_is_binary, conn))
 		goto failure;
@@ -1335,7 +1373,7 @@ getCopyStart(PGconn *conn, ExecStatusType copytype)
 		result->attDescs = (PGresAttDesc *)
 			pqResultAlloc(result, nfields * sizeof(PGresAttDesc), TRUE);
 		if (!result->attDescs)
-			goto failure;
+			goto oom_error;
 		MemSet(result->attDescs, 0, nfields * sizeof(PGresAttDesc));
 	}
 
@@ -1359,8 +1397,17 @@ getCopyStart(PGconn *conn, ExecStatusType copytype)
 	return 0;
 
 failure:
-	PQclear(result);
+	if (result)
+		PQclear(result);
 	return EOF;
+
+oom_error:
+	if (result)
+		PQclear(result);
+	printfPQExpBuffer(&conn->errorMessage,
+					  libpq_gettext("out of memory\n"));
+	pqSaveErrorResult(conn);
+	return 0;
 }
 
 /*
