Skip to content

Commit decdaf3

Browse files
committed
Improve pg_dump and psql to use libpq's newer COPY support routines,
instead of the old deprecated ones. Volkan Yazici, with some editorializing by moi.
1 parent 0b1b010 commit decdaf3

File tree

4 files changed

+145
-134
lines changed

4 files changed

+145
-134
lines changed

src/bin/pg_dump/pg_backup_db.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Implements the basic DB functions used by the archiver.
66
*
77
* IDENTIFICATION
8-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.69 2006/02/12 06:11:50 momjian Exp $
8+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.70 2006/03/03 23:38:29 tgl Exp $
99
*
1010
*-------------------------------------------------------------------------
1111
*/
@@ -391,22 +391,29 @@ _sendCopyLine(ArchiveHandle *AH, char *qry, char *eos)
391391
* enter COPY mode; this allows us to behave reasonably when trying
392392
* to continue after an error in a COPY command.
393393
*/
394-
if (AH->pgCopyIn && PQputline(AH->connection, AH->pgCopyBuf->data) != 0)
395-
die_horribly(AH, modulename, "error returned by PQputline: %s",
394+
if (AH->pgCopyIn &&
395+
PQputCopyData(AH->connection, AH->pgCopyBuf->data,
396+
AH->pgCopyBuf->len) <= 0)
397+
die_horribly(AH, modulename, "error returned by PQputCopyData: %s",
396398
PQerrorMessage(AH->connection));
397399

398400
resetPQExpBuffer(AH->pgCopyBuf);
399401

400-
/*
401-
* fprintf(stderr, "Buffer is '%s'\n", AH->pgCopyBuf->data);
402-
*/
403-
404-
if (isEnd)
402+
if (isEnd && AH->pgCopyIn)
405403
{
406-
if (AH->pgCopyIn && PQendcopy(AH->connection) != 0)
407-
die_horribly(AH, modulename, "error returned by PQendcopy: %s",
404+
PGresult *res;
405+
406+
if (PQputCopyEnd(AH->connection, NULL) <= 0)
407+
die_horribly(AH, modulename, "error returned by PQputCopyEnd: %s",
408408
PQerrorMessage(AH->connection));
409409

410+
/* Check command status and return to normal libpq state */
411+
res = PQgetResult(AH->connection);
412+
if (PQresultStatus(res) != PGRES_COMMAND_OK)
413+
warn_or_die_horribly(AH, modulename, "COPY failed: %s",
414+
PQerrorMessage(AH->connection));
415+
PQclear(res);
416+
410417
AH->pgCopyIn = false;
411418
}
412419

src/bin/pg_dump/pg_dump.c

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* by PostgreSQL
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.431 2006/03/02 01:18:25 tgl Exp $
15+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.432 2006/03/03 23:38:29 tgl Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -831,8 +831,6 @@ selectDumpableObject(DumpableObject *dobj)
831831
* to be dumped.
832832
*/
833833

834-
#define COPYBUFSIZ 8192
835-
836834
static int
837835
dumpTableData_copy(Archive *fout, void *dcontext)
838836
{
@@ -844,8 +842,7 @@ dumpTableData_copy(Archive *fout, void *dcontext)
844842
PQExpBuffer q = createPQExpBuffer();
845843
PGresult *res;
846844
int ret;
847-
bool copydone;
848-
char copybuf[COPYBUFSIZ];
845+
char *copybuf;
849846
const char *column_list;
850847

851848
if (g_verbose)
@@ -886,41 +883,27 @@ dumpTableData_copy(Archive *fout, void *dcontext)
886883
}
887884
res = PQexec(g_conn, q->data);
888885
check_sql_result(res, g_conn, q->data, PGRES_COPY_OUT);
886+
PQclear(res);
889887

890-
copydone = false;
891-
892-
while (!copydone)
888+
for (;;)
893889
{
894-
ret = PQgetline(g_conn, copybuf, COPYBUFSIZ);
890+
ret = PQgetCopyData(g_conn, &copybuf, 0);
891+
892+
if (ret < 0)
893+
break; /* done or error */
895894

896-
if (copybuf[0] == '\\' &&
897-
copybuf[1] == '.' &&
898-
copybuf[2] == '\0')
895+
if (copybuf)
899896
{
900-
copydone = true; /* don't print this... */
901-
}
902-
else
903-
{
904-
archputs(copybuf, fout);
905-
switch (ret)
906-
{
907-
case EOF:
908-
copydone = true;
909-
/* FALLTHROUGH */
910-
case 0:
911-
archputs("\n", fout);
912-
break;
913-
case 1:
914-
break;
915-
}
897+
WriteData(fout, copybuf, ret);
898+
PQfreemem(copybuf);
916899
}
917900

918901
/*
919902
* THROTTLE:
920903
*
921904
* There was considerable discussion in late July, 2000 regarding
922905
* slowing down pg_dump when backing up large tables. Users with both
923-
* slow & fast (muti-processor) machines experienced performance
906+
* slow & fast (multi-processor) machines experienced performance
924907
* degradation when doing a backup.
925908
*
926909
* Initial attempts based on sleeping for a number of ms for each ms
@@ -957,16 +940,20 @@ dumpTableData_copy(Archive *fout, void *dcontext)
957940
}
958941
archprintf(fout, "\\.\n\n\n");
959942

960-
ret = PQendcopy(g_conn);
961-
if (ret != 0)
943+
if (ret == -2)
962944
{
963-
write_msg(NULL, "SQL command to dump the contents of table \"%s\" failed: PQendcopy() failed.\n", classname);
945+
/* copy data transfer failed */
946+
write_msg(NULL, "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.\n", classname);
964947
write_msg(NULL, "Error message from server: %s", PQerrorMessage(g_conn));
965948
write_msg(NULL, "The command was: %s\n", q->data);
966949
exit_nicely();
967950
}
968951

952+
/* Check command status and return to normal libpq state */
953+
res = PQgetResult(g_conn);
954+
check_sql_result(res, g_conn, q->data, PGRES_COMMAND_OK);
969955
PQclear(res);
956+
970957
destroyPQExpBuffer(q);
971958
return 1;
972959
}

src/bin/psql/common.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* Copyright (c) 2000-2005, PostgreSQL Global Development Group
55
*
6-
* $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.112 2006/02/12 03:30:21 tgl Exp $
6+
* $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.113 2006/03/03 23:38:30 tgl Exp $
77
*/
88
#include "postgres_fe.h"
99
#include "common.h"
@@ -685,7 +685,10 @@ AcceptResult(const PGresult *result, const char *query)
685685
break;
686686

687687
case PGRES_COPY_OUT:
688-
/* keep cancel connection for copy out state */
688+
/*
689+
* Keep cancel connection active during copy out state.
690+
* The matching ResetCancelConn() is in handleCopyOut.
691+
*/
689692
SetCancelConn();
690693
break;
691694

@@ -702,6 +705,7 @@ AcceptResult(const PGresult *result, const char *query)
702705
psql_error("%s", error);
703706

704707
ReportSyntaxErrorPosition(result, query);
708+
705709
CheckConnection();
706710
}
707711

@@ -720,6 +724,9 @@ AcceptResult(const PGresult *result, const char *query)
720724
* is true; nothing special is done when start_xact is false. Typically,
721725
* start_xact = false is used for SELECTs and explicit BEGIN/COMMIT commands.
722726
*
727+
* Caller is responsible for handling the ensuing processing if a COPY
728+
* command is sent.
729+
*
723730
* Note: we don't bother to check PQclientEncoding; it is assumed that no
724731
* caller uses this path to issue "SET CLIENT_ENCODING".
725732
*/

0 commit comments

Comments
 (0)