*** a/src/bin/psql/common.c --- b/src/bin/psql/common.c *************** *** 691,709 **** ProcessResult(PGresult **results) */ SetCancelConn(); if (result_status == PGRES_COPY_OUT) ! success = handleCopyOut(pset.db, pset.queryFout) && success; else success = handleCopyIn(pset.db, pset.cur_cmd_source, ! PQbinaryTuples(*results)) && success; ResetCancelConn(); /* * Call PQgetResult() once more. In the typical case of a * single-command string, it will return NULL. Otherwise, we'll * have other results to process that may include other COPYs. */ ! PQclear(*results); ! *results = next_result = PQgetResult(pset.db); } else if (first_cycle) /* fast path: no COPY commands; PQexec visited all results */ --- 691,713 ---- */ SetCancelConn(); if (result_status == PGRES_COPY_OUT) ! success = handleCopyOut(pset.db, pset.queryFout, results) && success; else success = handleCopyIn(pset.db, pset.cur_cmd_source, ! PQbinaryTuples(*results), results) && success; ResetCancelConn(); /* * Call PQgetResult() once more. In the typical case of a * single-command string, it will return NULL. Otherwise, we'll * have other results to process that may include other COPYs. + * If it is NULL, then the last result will be returned back. */ ! if ((next_result = PQgetResult(pset.db))) ! { ! PQclear(*results); ! *results = next_result; ! } } else if (first_cycle) /* fast path: no COPY commands; PQexec visited all results */ *** a/src/bin/psql/copy.c --- b/src/bin/psql/copy.c *************** *** 433,444 **** do_copy(const char *args) * result is true if successful, false if not. */ bool ! handleCopyOut(PGconn *conn, FILE *copystream) { bool OK = true; char *buf; int ret; - PGresult *res; for (;;) { --- 433,443 ---- * result is true if successful, false if not. */ bool ! handleCopyOut(PGconn *conn, FILE *copystream, PGresult **res) { bool OK = true; char *buf; int ret; for (;;) { *************** *** 490,508 **** handleCopyOut(PGconn *conn, FILE *copystream) * TO STDOUT commands. We trust that no condition can make PQexec() fail * indefinitely while retaining status PGRES_COPY_OUT. */ ! while (res = PQgetResult(conn), PQresultStatus(res) == PGRES_COPY_OUT) { OK = false; ! PQclear(res); PQexec(conn, "-- clear PGRES_COPY_OUT state"); } ! if (PQresultStatus(res) != PGRES_COMMAND_OK) { psql_error("%s", PQerrorMessage(conn)); OK = false; } - PQclear(res); return OK; } --- 489,506 ---- * TO STDOUT commands. We trust that no condition can make PQexec() fail * indefinitely while retaining status PGRES_COPY_OUT. */ ! while (*res = PQgetResult(conn), PQresultStatus(*res) == PGRES_COPY_OUT) { OK = false; ! PQclear(*res); PQexec(conn, "-- clear PGRES_COPY_OUT state"); } ! if (PQresultStatus(*res) != PGRES_COMMAND_OK) { psql_error("%s", PQerrorMessage(conn)); OK = false; } return OK; } *************** *** 523,534 **** handleCopyOut(PGconn *conn, FILE *copystream) #define COPYBUFSIZ 8192 bool ! handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary) { bool OK; const char *prompt; char buf[COPYBUFSIZ]; - PGresult *res; /* * Establish longjmp destination for exiting from wait-for-input. (This is --- 521,531 ---- #define COPYBUFSIZ 8192 bool ! handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res) { bool OK; const char *prompt; char buf[COPYBUFSIZ]; /* * Establish longjmp destination for exiting from wait-for-input. (This is *************** *** 682,700 **** copyin_cleanup: * indefinitely while retaining status PGRES_COPY_IN, we get an infinite * loop. This is more realistic than handleCopyOut()'s counterpart risk. */ ! while (res = PQgetResult(conn), PQresultStatus(res) == PGRES_COPY_IN) { OK = false; ! PQclear(res); PQputCopyEnd(pset.db, _("trying to exit copy mode")); } ! if (PQresultStatus(res) != PGRES_COMMAND_OK) { psql_error("%s", PQerrorMessage(conn)); OK = false; } - PQclear(res); return OK; } --- 679,696 ---- * indefinitely while retaining status PGRES_COPY_IN, we get an infinite * loop. This is more realistic than handleCopyOut()'s counterpart risk. */ ! while (*res = PQgetResult(conn), PQresultStatus(*res) == PGRES_COPY_IN) { OK = false; ! PQclear(*res); PQputCopyEnd(pset.db, _("trying to exit copy mode")); } ! if (PQresultStatus(*res) != PGRES_COMMAND_OK) { psql_error("%s", PQerrorMessage(conn)); OK = false; } return OK; } *** a/src/bin/psql/copy.h --- b/src/bin/psql/copy.h *************** *** 16,22 **** bool do_copy(const char *args); /* lower level processors for copy in/out streams */ ! bool handleCopyOut(PGconn *conn, FILE *copystream); ! bool handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary); #endif --- 16,22 ---- /* lower level processors for copy in/out streams */ ! bool handleCopyOut(PGconn *conn, FILE *copystream, PGresult **res); ! bool handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res); #endif