aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/libpq/fe-misc.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index 2d44845ccb2..45a1d618300 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -825,6 +825,10 @@ definitelyFailed:
* Return 0 on success, -1 on failure and 1 when not all data could be sent
* because the socket would block and the connection is non-blocking.
*
+ * Note that this is also responsible for consuming data from the socket
+ * (putting it in conn->inBuffer) in any situation where we can't send
+ * all the specified data immediately.
+ *
* Upon write failure, conn->write_failed is set and the error message is
* saved in conn->write_err_msg, but we clear the output buffer and return
* zero anyway; this is because callers should soldier on until it's possible
@@ -844,12 +848,20 @@ pqSendSome(PGconn *conn, int len)
* on that connection. Even if the kernel would let us, we've probably
* lost message boundary sync with the server. conn->write_failed
* therefore persists until the connection is reset, and we just discard
- * all data presented to be written.
+ * all data presented to be written. However, as long as we still have a
+ * valid socket, we should continue to absorb data from the backend, so
+ * that we can collect any final error messages.
*/
if (conn->write_failed)
{
/* conn->write_err_msg should be set up already */
conn->outCount = 0;
+ /* Absorb input data if any, and detect socket closure */
+ if (conn->sock != PGINVALID_SOCKET)
+ {
+ if (pqReadData(conn) < 0)
+ return -1;
+ }
return 0;
}
@@ -919,6 +931,13 @@ pqSendSome(PGconn *conn, int len)
/* Discard queued data; no chance it'll ever be sent */
conn->outCount = 0;
+
+ /* Absorb input data if any, and detect socket closure */
+ if (conn->sock != PGINVALID_SOCKET)
+ {
+ if (pqReadData(conn) < 0)
+ return -1;
+ }
return 0;
}
}