From: Tom Lane Date: Sun, 5 Feb 2006 20:59:06 +0000 (+0000) Subject: Fix pg_restore to properly discard COPY data when trying to continue X-Git-Tag: REL8_0_7~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f9ce97c5a11838444fd4f063a2568f8c3c8777a7;p=thirdparty%2Fpostgresql.git Fix pg_restore to properly discard COPY data when trying to continue after an error in a COPY statement. Formerly it thought the COPY data was SQL commands, and got quite confused. Stephen Frost --- diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index 9febb145683..e9af7d5fd06 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.101.4.8 2005/09/11 00:36:35 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.101.4.9 2006/02/05 20:59:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -345,10 +345,15 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt) * mode with libpq. */ if (te->copyStmt && strlen(te->copyStmt) > 0) + { ahprintf(AH, "%s", te->copyStmt); + AH->writingCopyData = true; + } (*AH->PrintTocDataPtr) (AH, te, ropt); + AH->writingCopyData = false; + /* * If we just restored blobs, fix references in * previously-loaded tables; otherwise, if we diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h index e494a766f9a..b3037d5c33c 100644 --- a/src/bin/pg_dump/pg_backup_archiver.h +++ b/src/bin/pg_dump/pg_backup_archiver.h @@ -17,7 +17,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.62.4.1 2005/01/25 22:44:47 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.62.4.2 2006/02/05 20:59:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -244,7 +244,8 @@ typedef struct _archiveHandle int blobTxActive; /* Flag set if TX active on blobConnection */ int connectToDB; /* Flag to indicate if direct DB * connection is required */ - int pgCopyIn; /* Currently in libpq 'COPY IN' mode. */ + bool writingCopyData; /* True when we are sending COPY data */ + bool pgCopyIn; /* Currently in libpq 'COPY IN' mode. */ PQExpBuffer pgCopyBuf; /* Left-over data from incomplete lines in * COPY IN */ diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c index 50c0f4606dc..8135e50ae19 100644 --- a/src/bin/pg_dump/pg_backup_db.c +++ b/src/bin/pg_dump/pg_backup_db.c @@ -5,7 +5,7 @@ * Implements the basic DB functions used by the archiver. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.61.4.1 2005/07/27 05:15:03 neilc Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.61.4.2 2006/02/05 20:59:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -319,7 +319,7 @@ _executeSqlCommand(ArchiveHandle *AH, PGconn *conn, PQExpBuffer qry, char *desc) if (conn != AH->connection) die_horribly(AH, modulename, "COPY command executed in non-primary connection\n"); - AH->pgCopyIn = 1; + AH->pgCopyIn = true; } else { @@ -406,7 +406,7 @@ _sendCopyLine(ArchiveHandle *AH, char *qry, char *eos) *--------- */ - if (PQputline(AH->connection, AH->pgCopyBuf->data) != 0) + if (AH->pgCopyIn && PQputline(AH->connection, AH->pgCopyBuf->data) != 0) die_horribly(AH, modulename, "error returned by PQputline\n"); resetPQExpBuffer(AH->pgCopyBuf); @@ -417,10 +417,10 @@ _sendCopyLine(ArchiveHandle *AH, char *qry, char *eos) if (isEnd) { - if (PQendcopy(AH->connection) != 0) + if (AH->pgCopyIn && PQendcopy(AH->connection) != 0) die_horribly(AH, modulename, "error returned by PQendcopy\n"); - AH->pgCopyIn = 0; + AH->pgCopyIn = false; } return qry + loc + 1; @@ -658,7 +658,10 @@ ExecuteSqlCommandBuf(ArchiveHandle *AH, void *qryv, size_t bufLen) /* Could switch between command and COPY IN mode at each line */ while (qry < eos) { - if (AH->pgCopyIn) + /* If we are in CopyIn mode *or* if the upper-layers believe we're doing + * a COPY then call sendCopyLine. If we're not actually in CopyIn mode + * the sendCopyLine will just dump the data coming in */ + if (AH->pgCopyIn || AH->writingCopyData) qry = _sendCopyLine(AH, qry, eos); else qry = _sendSQLLine(AH, qry, eos);