- Fix help output: replace 'f' with 't' and change desc
authorPhilip Warner
Tue, 13 Feb 2001 01:31:54 +0000 (01:31 +0000)
committerPhilip Warner
Tue, 13 Feb 2001 01:31:54 +0000 (01:31 +0000)
- Add extra arg to formatStringLiteral to specify how to handle LF & TAB.
  I opted for encoding them except in procedure bodies & comments
- Fixed bug in tar file input when restoring blobs

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

index 634c10888b7d9ff1fd5f2c0ad9a21eef97c14333..ebbfdb31d88efada1cbf2c3696b2dbc4d4f50794 100644 (file)
@@ -62,7 +62,7 @@ typedef z_stream *z_streamp;
 
 #define K_VERS_MAJOR 1
 #define K_VERS_MINOR 4 
-#define K_VERS_REV 27 
+#define K_VERS_REV 28 
 
 /* Data block types */
 #define BLK_DATA 1
index 40d90ac865233f789ca7eaa5b74c99e94f457b90..87dada274d5bdc6a56ade0e9ec638eda8480b2b5 100644 (file)
@@ -1061,26 +1061,53 @@ static int _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER* th)
    int             sum, chk;
    int             len;
    int             hPos;
+   int             i;
+   bool            gotBlock = false;
 
-   /*
-    * if ( ftell(ctx->tarFH) != ctx->tarFHpos)
-    *      die_horribly(AH, "%s: mismatch in actual vs. predicted file pos - %d vs. %d\n",
-    *                      progname, ftell(ctx->tarFH), ctx->tarFHpos);
-    */
+   while (!gotBlock)
+   {
+       /*
+        * if ( ftell(ctx->tarFH) != ctx->tarFHpos)
+        *      die_horribly(AH, "%s: mismatch in actual vs. predicted file pos - %d vs. %d\n",
+        *                      progname, ftell(ctx->tarFH), ctx->tarFHpos);
+        */
 
-   hPos = ctx->tarFHpos;
+       /* Save the pos for reporting purposes */
+       hPos = ctx->tarFHpos;
 
-   len = _tarReadRaw(AH, &h[0], 512, NULL, ctx->tarFH);
-   if (len == 0) /* EOF */
-       return 0;
+       /* Read a 512 byte block, return EOF, exit if short */
+       len = _tarReadRaw(AH, &h[0], 512, NULL, ctx->tarFH);
+       if (len == 0) /* EOF */
+           return 0;
+
+       if (len != 512)
+           die_horribly(AH, "%s: incomplete tar header found (%d bytes)\n", progname, len);
+
+       /* Calc checksum */
+       chk = _tarChecksum(&h[0]);
 
-   if (len != 512)
-       die_horribly(AH, "%s: incomplete tar header found (%d bytes)\n", progname, len);
+       /*
+        * If the checksum failed, see if it is a null block.
+        * If so, then just try with next block...
+        */
+
+       if (chk == sum) {
+           gotBlock = true;
+       } else {
+           for( i = 0 ; i < 512 ; i++)
+           {
+               if (h[0] != 0) 
+               {
+                   gotBlock = true;    
+                   break;
+               }
+           }
+       }
+   }
 
    sscanf(&h[0], "%99s", &name[0]);
    sscanf(&h[124], "%12o", &len);
    sscanf(&h[148], "%8o", &sum);
-   chk = _tarChecksum(&h[0]);
 
    ahlog(AH, 3, "TOC Entry %s at %d (len=%d, chk=%d)\n", &name[0], hPos, len, sum);
 
index 77447f403b107dfba23785f28c909b15a12e7b42..c0387983189aed9f5de276b2a28a333d3d2a0fb3 100644 (file)
@@ -22,7 +22,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.191 2001/02/10 02:31:27 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.192 2001/02/13 01:31:54 pjw Exp $
  *
  * Modifications - 6/10/96 - [email protected] - version 1.13.dhb
  *
  *     table with the currently implementation, and (b) it's not clear how to restore
  *     a partial BLOB backup (given the current OID-based BLOB implementation).
  *
- * Modifications - 04-Jan-2000 - [email protected]
+ * Modifications - 04-Jan-2001 - [email protected]
  *
  *   - Check ntuples == 1 for various SELECT statements.
  *   - Fix handling of --tables=* (multiple tables never worked properly, AFAICT)
  *
+ * Modifications - 13-Feb-2001 - [email protected]
+ *
+ *    - Fix help output: replace 'f' with 't' and change desc.
+ *    - Add extra arg to formatStringLiteral to specify how to handle LF & TAB.
+ *      I opted for encoding them except in procedure bodies.
+ * 
  *-------------------------------------------------------------------------
  */
 
 
 #define atooid(x)  ((Oid) strtoul((x), NULL, 10))
 
+
+typedef enum _formatLiteralOptions {
+        CONV_ALL = 0,
+        PASS_LFTAB = 3 /* NOTE: 1 and 2 are reserved in case we want to make a mask. */ 
+                       /* We could make this a bit mask for control chars, but I don't */
+                       /* see any value in making it more complex...the current code */
+                       /* only checks for 'opts == CONV_ALL' anyway. */
+} formatLiteralOptions;
+
 static void dumpComment(Archive *outfile, const char *target, const char *oid);
 static void dumpSequence(Archive *fout, TableInfo tbinfo);
 static void dumpACL(Archive *fout, TableInfo tbinfo);
@@ -147,7 +162,7 @@ static void dumpTriggers(Archive *fout, const char *tablename,
             TableInfo *tblinfo, int numTables);
 static void dumpRules(Archive *fout, const char *tablename,
          TableInfo *tblinfo, int numTables);
-static void formatStringLiteral(PQExpBuffer buf, const char *str);
+static void formatStringLiteral(PQExpBuffer buf, const char *str, const formatLiteralOptions opts);
 static void clearTableInfo(TableInfo *, int);
 static void dumpOneFunc(Archive *fout, FuncInfo *finfo, int i,
            TypeInfo *tinfo, int numTypes);
@@ -209,7 +224,7 @@ help(const char *progname)
        "  -d, --inserts            dump data as INSERT, rather than COPY, commands\n"
        "  -D, --attribute-inserts  dump data as INSERT commands with attribute names\n"
        "  -f, --file=FILENAME      specify output file name\n"
-       "  -F, --format {c|f|p}     output file format (custom, files, plain text)\n"
+       "  -F, --format {c|t|p}     output file format (custom, tar, plain text)\n"
        "  -h, --host=HOSTNAME      server host name\n"
        "  -i, --ignore-version     proceed when database version != pg_dump version\n"
        "  -n, --no-quotes          suppress most quotes around identifiers\n"
@@ -238,7 +253,7 @@ help(const char *progname)
        "  -d                       dump data as INSERT, rather than COPY, commands\n"
        "  -D                       dump data as INSERT commands with attribute names\n"
        "  -f FILENAME              specify output file name\n"
-       "  -F {c|f|p}               output file format (custom, files, plain text)\n"
+       "  -F {c|t|p}               output file format (custom, tar, plain text)\n"
        "  -h HOSTNAME              server host name\n"
        "  -i                       proceed when database version != pg_dump version\n"
        "  -n                       suppress most quotes around identifiers\n"
@@ -509,7 +524,7 @@ dumpClasses_dumpData(Archive *fout, char* oid, void *dctxv)
                     * with appropriate escaping of special characters.
                     */
                    resetPQExpBuffer(q);
-                   formatStringLiteral(q, PQgetvalue(res, tuple, field));
+                   formatStringLiteral(q, PQgetvalue(res, tuple, field), CONV_ALL);
                    archprintf(fout, "%s", q->data);
                    break;
            }
@@ -528,7 +543,7 @@ dumpClasses_dumpData(Archive *fout, char* oid, void *dctxv)
  * The literal is appended to the given PQExpBuffer.
  */
 static void
-formatStringLiteral(PQExpBuffer buf, const char *str)
+formatStringLiteral(PQExpBuffer buf, const char *str, const formatLiteralOptions opts)
 {
    appendPQExpBufferChar(buf, '\'');
    while (*str)
@@ -541,7 +556,9 @@ formatStringLiteral(PQExpBuffer buf, const char *str)
            appendPQExpBufferChar(buf, ch);
        }
        else if ((unsigned char) ch < (unsigned char) ' ' &&
-                ch != '\n' && ch != '\t')
+               (       opts == CONV_ALL
+                   ||  (ch != '\n' && ch != '\t')
+               ))
        {
            /* generate octal escape for control chars other than whitespace */
            appendPQExpBufferChar(buf, '\\');
@@ -1099,7 +1116,7 @@ dumpDatabase(Archive *AH)
    /* Get the dba */
    appendPQExpBuffer(dbQry, "select (select usename from pg_user where datdba = usesysid) as dba from pg_database"
                            " where datname = ");
-   formatStringLiteral(dbQry, PQdb(g_conn));
+   formatStringLiteral(dbQry, PQdb(g_conn), CONV_ALL);
 
    res = PQexec(g_conn, dbQry->data);
    if (!res ||
@@ -1988,7 +2005,7 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
 
            resetPQExpBuffer(query);
            appendPQExpBuffer(query, "SELECT pg_get_viewdef(");
-           formatStringLiteral(query, tblinfo[i].relname);
+           formatStringLiteral(query, tblinfo[i].relname, CONV_ALL);
            appendPQExpBuffer(query, ") as viewdef");
            res2 = PQexec(g_conn, query->data);
            if (!res2 || PQresultStatus(res2) != PGRES_TUPLES_OK)
@@ -2823,7 +2840,7 @@ dumpComment(Archive *fout, const char *target, const char *oid)
        i_description = PQfnumber(res, "description");
        resetPQExpBuffer(query);
        appendPQExpBuffer(query, "COMMENT ON %s IS ", target);
-       formatStringLiteral(query, PQgetvalue(res, 0, i_description));
+       formatStringLiteral(query, PQgetvalue(res, 0, i_description), PASS_LFTAB);
        appendPQExpBuffer(query, ";\n");
 
        ArchiveEntry(fout, oid, target, "COMMENT", NULL, query->data, "" /*Del*/,
@@ -2859,7 +2876,7 @@ dumpDBComment(Archive *fout)
 
    query = createPQExpBuffer();
    appendPQExpBuffer(query, "SELECT oid FROM pg_database WHERE datname = ");
-   formatStringLiteral(query, PQdb(g_conn));
+   formatStringLiteral(query, PQdb(g_conn), CONV_ALL);
 
    /*** Execute query ***/
 
@@ -2947,7 +2964,7 @@ dumpTypes(Archive *fout, FuncInfo *finfo, int numFuncs,
                          fmtId(tinfo[i].typsend, force_quotes));
        appendPQExpBuffer(q, " receive = %s, default = ",
                          fmtId(tinfo[i].typreceive, force_quotes));
-       formatStringLiteral(q, tinfo[i].typdefault);
+       formatStringLiteral(q, tinfo[i].typdefault, CONV_ALL);
 
        if (tinfo[i].isArray)
        {
@@ -2964,7 +2981,7 @@ dumpTypes(Archive *fout, FuncInfo *finfo, int numFuncs,
            }
 
            appendPQExpBuffer(q, ", element = %s, delimiter = ", elemType);
-           formatStringLiteral(q, tinfo[i].typdelim);
+           formatStringLiteral(q, tinfo[i].typdelim, CONV_ALL);
        }
        if (tinfo[i].passedbyvalue)
            appendPQExpBuffer(q, ",passedbyvalue);\n");
@@ -3057,16 +3074,16 @@ dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs,
        lancompiler = PQgetvalue(res, i, i_lancompiler);
 
        appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE ");
-       formatStringLiteral(delqry, lanname);
+       formatStringLiteral(delqry, lanname, CONV_ALL);
        appendPQExpBuffer(delqry, ";\n");
 
        appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE ",
                          (PQgetvalue(res, i, i_lanpltrusted)[0] == 't') ?
                          "TRUSTED " : "");
-       formatStringLiteral(defqry, lanname);
+       formatStringLiteral(defqry, lanname, CONV_ALL);
        appendPQExpBuffer(defqry, " HANDLER %s LANCOMPILER ",
                          fmtId(finfo[fidx].proname, force_quotes));
-       formatStringLiteral(defqry, lancompiler);
+       formatStringLiteral(defqry, lancompiler, CONV_ALL);
        appendPQExpBuffer(defqry, ";\n");
 
        ArchiveEntry(fout, PQgetvalue(res, i, i_oid), lanname, "PROCEDURAL LANGUAGE",
@@ -3156,11 +3173,11 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo, int i,
    if (strcmp(finfo[i].probin, "-") != 0)
    {
        appendPQExpBuffer(asPart, "AS ");
-       formatStringLiteral(asPart, finfo[i].probin);
+       formatStringLiteral(asPart, finfo[i].probin, CONV_ALL);
        if (strcmp(finfo[i].prosrc, "-") != 0)
        {
            appendPQExpBuffer(asPart, ", ");
-           formatStringLiteral(asPart, finfo[i].prosrc);
+           formatStringLiteral(asPart, finfo[i].prosrc, PASS_LFTAB);
        }
    }
    else
@@ -3168,7 +3185,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo, int i,
        if (strcmp(finfo[i].prosrc, "-") != 0)
        {
            appendPQExpBuffer(asPart, "AS ");
-           formatStringLiteral(asPart, finfo[i].prosrc);
+           formatStringLiteral(asPart, finfo[i].prosrc, PASS_LFTAB);
        }
    }
 
@@ -3233,7 +3250,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo, int i,
                      (finfo[i].retset) ? "SETOF " : "",
                      rettypename,
                      asPart->data);
-   formatStringLiteral(q, func_lang);
+   formatStringLiteral(q, func_lang, CONV_ALL);
 
    if (finfo[i].iscachable || finfo[i].isstrict) /* OR in new attrs here */
    {
@@ -3477,7 +3494,7 @@ dumpAggs(Archive *fout, AggInfo *agginfo, int numAggs,
        if (agginfo[i].agginitval)
        {
            appendPQExpBuffer(details, ", INITCOND = ");
-           formatStringLiteral(details, agginfo[i].agginitval);
+           formatStringLiteral(details, agginfo[i].agginitval, CONV_ALL);
        }
 
        if (!(strcmp(agginfo[i].aggfinalfn, "-") == 0))
@@ -4267,7 +4284,7 @@ findLastBuiltinOid(const char* dbname)
 
    resetPQExpBuffer(query);
    appendPQExpBuffer(query, "SELECT datlastsysoid from pg_database where datname = ");
-   formatStringLiteral(query, dbname);
+   formatStringLiteral(query, dbname, CONV_ALL);
 
    res = PQexec(g_conn, query->data);
    if (res == NULL ||
@@ -4376,7 +4393,7 @@ dumpSequence(Archive *fout, TableInfo tbinfo)
 
    resetPQExpBuffer(query);
    appendPQExpBuffer(query, "SELECT setval (");
-   formatStringLiteral(query, fmtId(tbinfo.relname, force_quotes));
+   formatStringLiteral(query, fmtId(tbinfo.relname, force_quotes), CONV_ALL);
    appendPQExpBuffer(query, ", %d, '%c');\n", last, called);
 
    ArchiveEntry(fout, tbinfo.oid, fmtId(tbinfo.relname, force_quotes), "SEQUENCE SET", NULL,
@@ -4458,7 +4475,7 @@ dumpRules(Archive *fout, const char *tablename,
                          "   pg_rewrite.oid, pg_rewrite.rulename "
                          "FROM pg_rewrite, pg_class, pg_rules "
                          "WHERE pg_class.relname = ");
-       formatStringLiteral(query, tblinfo[t].relname);
+       formatStringLiteral(query, tblinfo[t].relname, CONV_ALL);
        appendPQExpBuffer(query,
                          "    AND pg_rewrite.ev_class = pg_class.oid "
                          "    AND pg_rules.tablename = pg_class.relname "