diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index 2d44845ccb..45a1d61830 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; } }