Fix pg_restore to properly discard COPY data when trying to continue
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 5 Feb 2006 20:59:06 +0000 (20:59 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 5 Feb 2006 20:59:06 +0000 (20:59 +0000)
after an error in a COPY statement.  Formerly it thought the COPY data
was SQL commands, and got quite confused.

Stephen Frost

src/bin/pg_dump/pg_backup_archiver.c
src/bin/pg_dump/pg_backup_archiver.h
src/bin/pg_dump/pg_backup_db.c

index 9febb145683bffe8cb8fde220c28918bf24fc7e3..e9af7d5fd06619edb282ca5be4816aa2384aa8f0 100644 (file)
@@ -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
index e494a766f9af70af611ce59c7024f3decded6552..b3037d5c33c0e23c6a3c0d9ccaee0128a4f290a2 100644 (file)
@@ -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 */
 
index 50c0f4606dc84fc6aa8f553aaddad09c7b43af24..8135e50ae192321f35c2b3ca5e6051563197887d 100644 (file)
@@ -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);