diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2e13e1daa4f960cdb9f4669f5ae26d6672aa6dd1..0aa134f4cdefbcd4af405d64d652f100e0821300 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.265 2008/09/22 14:21:44 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.266 2008/10/27 09:42:31 mha Exp $ -->
 
 <chapter id="libpq">
  <title><application>libpq</application> - C Library</title>
@@ -1137,10 +1137,11 @@ PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);
        Nearly all <application>libpq</> functions will set a message for
        <function>PQerrorMessage</function> if they fail.  Note that by
        <application>libpq</application> convention, a nonempty
-       <function>PQerrorMessage</function> result will include a trailing
-       newline. The caller should not free the result directly. It will
-       be freed when the associated <structname>PGconn</> handle is passed
-       to <function>PQfinish</function>.  The result string should not be
+       <function>PQerrorMessage</function> result can be multiple lines,
+       and will include a trailing newline. The caller should not free
+       the result directly. It will be freed when the associated
+       <structname>PGconn</> handle is passed to
+       <function>PQfinish</function>.  The result string should not be
        expected to remain the same across operations on the
        <literal>PGconn</> structure.
       </para>
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 54aa71039705d719f97ae1d0ee15349da585d1a6..c611c0de1cbf969033cd3eeb638684510de3935d 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.363 2008/10/23 16:17:19 mha Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.364 2008/10/27 09:42:31 mha Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -699,7 +699,7 @@ connectNoDelay(PGconn *conn)
 	{
 		char		sebuf[256];
 
-		printfPQExpBuffer(&conn->errorMessage,
+		appendPQExpBuffer(&conn->errorMessage,
 			libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
 						  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
 		return 0;
@@ -729,7 +729,7 @@ connectFailureMessage(PGconn *conn, int errorno)
 						   NULL, 0,
 						   service, sizeof(service),
 						   NI_NUMERICSERV);
-		printfPQExpBuffer(&conn->errorMessage,
+		appendPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("could not connect to server: %s\n"
 							"\tIs the server running locally and accepting\n"
 							"\tconnections on Unix domain socket \"%s\"?\n"),
@@ -739,7 +739,7 @@ connectFailureMessage(PGconn *conn, int errorno)
 	else
 #endif   /* HAVE_UNIX_SOCKETS */
 	{
-		printfPQExpBuffer(&conn->errorMessage,
+		appendPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("could not connect to server: %s\n"
 					 "\tIs the server running on host \"%s\" and accepting\n"
 										"\tTCP/IP connections on port %s?\n"),
@@ -829,11 +829,11 @@ connectDBStart(PGconn *conn)
 	if (ret || !addrs)
 	{
 		if (node)
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("could not translate host name \"%s\" to address: %s\n"),
 							  node, gai_strerror(ret));
 		else
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("could not translate Unix-domain socket path \"%s\" to address: %s\n"),
 							  portstr, gai_strerror(ret));
 		if (addrs)
@@ -924,6 +924,8 @@ connectDBComplete(PGconn *conn)
 		switch (flag)
 		{
 			case PGRES_POLLING_OK:
+				/* Reset stored error messages since we now have a working connection */
+				resetPQExpBuffer(&conn->errorMessage);
 				return 1;		/* success! */
 
 			case PGRES_POLLING_READING:
@@ -1033,7 +1035,7 @@ PQconnectPoll(PGconn *conn)
 			break;
 
 		default:
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext(
 											"invalid connection state, "
 								 "probably indicative of memory corruption\n"
@@ -1077,7 +1079,7 @@ keep_going:						/* We will come back to here until there is
 							conn->addr_cur = addr_cur->ai_next;
 							continue;
 						}
-						printfPQExpBuffer(&conn->errorMessage,
+						appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("could not create socket: %s\n"),
 							SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
 						break;
@@ -1100,7 +1102,7 @@ keep_going:						/* We will come back to here until there is
 					}
 					if (!pg_set_noblock(conn->sock))
 					{
-						printfPQExpBuffer(&conn->errorMessage,
+						appendPQExpBuffer(&conn->errorMessage,
 										  libpq_gettext("could not set socket to non-blocking mode: %s\n"),
 							SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
 						closesocket(conn->sock);
@@ -1112,7 +1114,7 @@ keep_going:						/* We will come back to here until there is
 #ifdef F_SETFD
 					if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1)
 					{
-						printfPQExpBuffer(&conn->errorMessage,
+						appendPQExpBuffer(&conn->errorMessage,
 										  libpq_gettext("could not set socket to close-on-exec mode: %s\n"),
 							SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
 						closesocket(conn->sock);
@@ -1199,7 +1201,7 @@ keep_going:						/* We will come back to here until there is
 				if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR,
 							   (char *) &optval, &optlen) == -1)
 				{
-					printfPQExpBuffer(&conn->errorMessage,
+					appendPQExpBuffer(&conn->errorMessage,
 					libpq_gettext("could not get socket error status: %s\n"),
 							SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
 					goto error_return;
@@ -1237,7 +1239,7 @@ keep_going:						/* We will come back to here until there is
 								(struct sockaddr *) & conn->laddr.addr,
 								&conn->laddr.salen) < 0)
 				{
-					printfPQExpBuffer(&conn->errorMessage,
+					appendPQExpBuffer(&conn->errorMessage,
 									  libpq_gettext("could not get client address from socket: %s\n"),
 							SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
 					goto error_return;
@@ -1281,7 +1283,7 @@ keep_going:						/* We will come back to here until there is
 					pv = htonl(NEGOTIATE_SSL_CODE);
 					if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
 					{
-						printfPQExpBuffer(&conn->errorMessage,
+						appendPQExpBuffer(&conn->errorMessage,
 										  libpq_gettext("could not send SSL negotiation packet: %s\n"),
 							SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
 						goto error_return;
@@ -1303,6 +1305,7 @@ keep_going:						/* We will come back to here until there is
 														EnvironmentOptions);
 				if (!startpacket)
 				{
+					/* will not appendbuffer here, since it's likely to also run out of memory */
 					printfPQExpBuffer(&conn->errorMessage,
 									  libpq_gettext("out of memory\n"));
 					goto error_return;
@@ -1316,7 +1319,7 @@ keep_going:						/* We will come back to here until there is
 				 */
 				if (pqPacketSend(conn, 0, startpacket, packetlen) != STATUS_OK)
 				{
-					printfPQExpBuffer(&conn->errorMessage,
+					appendPQExpBuffer(&conn->errorMessage,
 						libpq_gettext("could not send startup packet: %s\n"),
 							SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
 					free(startpacket);
@@ -1381,7 +1384,7 @@ keep_going:						/* We will come back to here until there is
 						if (conn->sslmode[0] == 'r')	/* "require" */
 						{
 							/* Require SSL, but server does not want it */
-							printfPQExpBuffer(&conn->errorMessage,
+							appendPQExpBuffer(&conn->errorMessage,
 											  libpq_gettext("server does not support SSL, but SSL was required\n"));
 							goto error_return;
 						}
@@ -1398,7 +1401,7 @@ keep_going:						/* We will come back to here until there is
 						if (conn->sslmode[0] == 'r')	/* "require" */
 						{
 							/* Require SSL, but server is too old */
-							printfPQExpBuffer(&conn->errorMessage,
+							appendPQExpBuffer(&conn->errorMessage,
 											  libpq_gettext("server does not support SSL, but SSL was required\n"));
 							goto error_return;
 						}
@@ -1414,7 +1417,7 @@ keep_going:						/* We will come back to here until there is
 					}
 					else
 					{
-						printfPQExpBuffer(&conn->errorMessage,
+						appendPQExpBuffer(&conn->errorMessage,
 										  libpq_gettext("received invalid response to SSL negotiation: %c\n"),
 										  SSLok);
 						goto error_return;
@@ -1489,7 +1492,7 @@ keep_going:						/* We will come back to here until there is
 				 */
 				if (!(beresp == 'R' || beresp == 'E'))
 				{
-					printfPQExpBuffer(&conn->errorMessage,
+					appendPQExpBuffer(&conn->errorMessage,
 									  libpq_gettext(
 									  "expected authentication request from "
 												"server, but received %c\n"),
@@ -1522,7 +1525,7 @@ keep_going:						/* We will come back to here until there is
 				 */
 				if (beresp == 'R' && (msgLength < 8 || msgLength > 2000))
 				{
-					printfPQExpBuffer(&conn->errorMessage,
+					appendPQExpBuffer(&conn->errorMessage,
 									  libpq_gettext(
 									  "expected authentication request from "
 												"server, but received %c\n"),
@@ -1534,7 +1537,7 @@ keep_going:						/* We will come back to here until there is
 				{
 					/* Handle error from a pre-3.0 server */
 					conn->inCursor = conn->inStart + 1; /* reread data */
-					if (pqGets(&conn->errorMessage, conn))
+					if (pqGets_append(&conn->errorMessage, conn))
 					{
 						/* We'll come back when there is more data */
 						return PGRES_POLLING_READING;
@@ -1601,7 +1604,7 @@ keep_going:						/* We will come back to here until there is
 					}
 					else
 					{
-						if (pqGets(&conn->errorMessage, conn))
+						if (pqGets_append(&conn->errorMessage, conn))
 						{
 							/* We'll come back when there is more data */
 							return PGRES_POLLING_READING;
@@ -1788,7 +1791,7 @@ keep_going:						/* We will come back to here until there is
 				if (res)
 				{
 					if (res->resultStatus != PGRES_FATAL_ERROR)
-						printfPQExpBuffer(&conn->errorMessage,
+						appendPQExpBuffer(&conn->errorMessage,
 										  libpq_gettext("unexpected message from server during startup\n"));
 
 					/*
@@ -1855,7 +1858,7 @@ keep_going:						/* We will come back to here until there is
 			return PGRES_POLLING_OK;
 
 		default:
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext(
 											"invalid connection state %c, "
 								 "probably indicative of memory corruption\n"
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index cc3e758ef2ecc2f65e183d141c83f80ad3a8111f..691262cf8abc62d2a83f49773f0477f69185b5e8 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -23,7 +23,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-misc.c,v 1.135 2008/08/20 11:53:45 mha Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-misc.c,v 1.136 2008/10/27 09:42:31 mha Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -106,14 +106,14 @@ pqPutc(char c, PGconn *conn)
 
 
 /*
- * pqGets:
+ * pqGets[_append]:
  * get a null-terminated string from the connection,
  * and store it in an expansible PQExpBuffer.
  * If we run out of memory, all of the string is still read,
  * but the excess characters are silently discarded.
  */
-int
-pqGets(PQExpBuffer buf, PGconn *conn)
+static int
+pqGets_internal(PQExpBuffer buf, PGconn *conn, bool resetbuffer)
 {
 	/* Copy conn data to locals for faster search loop */
 	char	   *inBuffer = conn->inBuffer;
@@ -129,7 +129,9 @@ pqGets(PQExpBuffer buf, PGconn *conn)
 
 	slen = inCursor - conn->inCursor;
 
-	resetPQExpBuffer(buf);
+	if (resetbuffer)
+		resetPQExpBuffer(buf);
+
 	appendBinaryPQExpBuffer(buf, inBuffer + conn->inCursor, slen);
 
 	conn->inCursor = ++inCursor;
@@ -141,6 +143,18 @@ pqGets(PQExpBuffer buf, PGconn *conn)
 	return 0;
 }
 
+int
+pqGets(PQExpBuffer buf, PGconn *conn)
+{
+	return pqGets_internal(buf, conn, true);
+}
+
+int
+pqGets_append(PQExpBuffer buf, PGconn *conn)
+{
+	return pqGets_internal(buf, conn, false);
+}
+
 
 /*
  * pqPuts: write a null-terminated string to the current message
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 66059493bb0788a475c1243d7b05c8d58aa259de..ba2798234f02d82a7befda100881cca6cd9b9b77 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol3.c,v 1.35 2008/05/29 22:02:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol3.c,v 1.36 2008/10/27 09:42:31 mha Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -853,7 +853,6 @@ pqGetErrorNotice3(PGconn *conn, bool isError)
 			goto fail;
 		pqClearAsyncResult(conn);
 		conn->result = res;
-		resetPQExpBuffer(&conn->errorMessage);
 		appendPQExpBufferStr(&conn->errorMessage, workBuf.data);
 	}
 	else
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 9702c616820914e460bcaad7a9459249d0e8da71..8525fb15f05906838dacf2c81dcfb589e492c8de 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.134 2008/09/22 14:21:44 tgl Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.135 2008/10/27 09:42:31 mha Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -519,6 +519,7 @@ extern int	pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn);
 extern int	pqGetc(char *result, PGconn *conn);
 extern int	pqPutc(char c, PGconn *conn);
 extern int	pqGets(PQExpBuffer buf, PGconn *conn);
+extern int	pqGets_append(PQExpBuffer buf, PGconn *conn);
 extern int	pqPuts(const char *s, PGconn *conn);
 extern int	pqGetnchar(char *s, size_t len, PGconn *conn);
 extern int	pqPutnchar(const char *s, size_t len, PGconn *conn);