1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-23 14:01:44 +03:00

Allow psql to print COPY command status in more cases.

Previously, psql would print the "COPY nnn" command status only for COPY
commands executed server-side.  Now it will print that for frontend copies
too (including \copy).  However, we continue to suppress the command status
for COPY TO STDOUT, since in that case the copy data has been routed to the
same place that the command status would go, and there is a risk of the
status line being mistaken for another line of COPY data.  Doing that would
break existing scripts, and it doesn't seem worth the benefit --- this case
seems fairly analogous to SELECT, for which we also suppress the command
status.

Kumar Rajeev Rastogi, with substantial review by Amit Khandekar
This commit is contained in:
Tom Lane
2014-03-13 13:49:03 -04:00
parent 7bae0284ee
commit f70a78bc1f
5 changed files with 82 additions and 48 deletions

View File

@ -429,16 +429,17 @@ do_copy(const char *args)
* conn should be a database connection that you just issued COPY TO on
* and got back a PGRES_COPY_OUT result.
* copystream is the file stream for the data to go to.
* The final status for the COPY is returned into *res (but note
* we already reported the error, if it's not a success result).
*
* result is true if successful, false if not.
*/
bool
handleCopyOut(PGconn *conn, FILE *copystream)
handleCopyOut(PGconn *conn, FILE *copystream, PGresult **res)
{
bool OK = true;
char *buf;
int ret;
PGresult *res;
for (;;)
{
@ -485,13 +486,12 @@ handleCopyOut(PGconn *conn, FILE *copystream)
* but hasn't exited COPY_OUT state internally. So we ignore the
* possibility here.
*/
res = PQgetResult(conn);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
*res = PQgetResult(conn);
if (PQresultStatus(*res) != PGRES_COMMAND_OK)
{
psql_error("%s", PQerrorMessage(conn));
OK = false;
}
PQclear(res);
return OK;
}
@ -504,6 +504,8 @@ handleCopyOut(PGconn *conn, FILE *copystream)
* and got back a PGRES_COPY_IN result.
* copystream is the file stream to read the data from.
* isbinary can be set from PQbinaryTuples().
* The final status for the COPY is returned into *res (but note
* we already reported the error, if it's not a success result).
*
* result is true if successful, false if not.
*/
@ -512,12 +514,11 @@ handleCopyOut(PGconn *conn, FILE *copystream)
#define COPYBUFSIZ 8192
bool
handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary)
handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res)
{
bool OK;
const char *prompt;
char buf[COPYBUFSIZ];
PGresult *res;
/*
* Establish longjmp destination for exiting from wait-for-input. (This is
@ -679,21 +680,20 @@ copyin_cleanup:
* connection is lost. But that's fine; it will get us out of COPY_IN
* state, which is what we need.)
*/
while (res = PQgetResult(conn), PQresultStatus(res) == PGRES_COPY_IN)
while (*res = PQgetResult(conn), PQresultStatus(*res) == PGRES_COPY_IN)
{
OK = false;
PQclear(res);
PQclear(*res);
/* We can't send an error message if we're using protocol version 2 */
PQputCopyEnd(conn,
(PQprotocolVersion(conn) < 3) ? NULL :
_("trying to exit copy mode"));
}
if (PQresultStatus(res) != PGRES_COMMAND_OK)
if (PQresultStatus(*res) != PGRES_COMMAND_OK)
{
psql_error("%s", PQerrorMessage(conn));
OK = false;
}
PQclear(res);
return OK;
}