pg_dump: Fix ArchiveEntry handling of some empty values
authorAlvaro Herrera <[email protected]>
Thu, 28 Feb 2019 20:16:08 +0000 (17:16 -0300)
committerAlvaro Herrera <[email protected]>
Thu, 28 Feb 2019 20:19:44 +0000 (17:19 -0300)
Commit f831d4acc changed what pg_dump emits for some empty fields: they
were output as empty strings before, NULL pointer afterwards.  That
makes old pg_restore unable to work (crash) with such files, which is
unacceptable.  Return to the original representation by explicitly
setting those struct members to "" where needed; remove some no longer
needed checks for NULL input.

We can declutter the code a little by returning to NULLs when we next
update the archive version, so add a note to remind us later.

Discussion: https://postgr.es/m/20190225074539[email protected]
Reported-by: hubert depesz lubaczewski
Author: Dmitry Dolgov

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

index 8b55f5952c3d78d3fe50d6e9636f76d9ec9492bb..0f1afeacf79a29044e8722488edf551eac76b199 100644 (file)
@@ -1090,10 +1090,10 @@ ArchiveEntry(Archive *AHX, CatalogId catalogId, DumpId dumpId,
    newToc->tag = pg_strdup(opts->tag);
    newToc->namespace = opts->namespace ? pg_strdup(opts->namespace) : NULL;
    newToc->tablespace = opts->tablespace ? pg_strdup(opts->tablespace) : NULL;
-   newToc->owner = opts->owner ? pg_strdup(opts->owner) : NULL;
+   newToc->owner = pg_strdup(opts->owner);
    newToc->desc = pg_strdup(opts->description);
-   newToc->defn = opts->createStmt ? pg_strdup(opts->createStmt) : NULL;
-   newToc->dropStmt = opts->dropStmt ? pg_strdup(opts->dropStmt) : NULL;
+   newToc->defn = pg_strdup(opts->createStmt);
+   newToc->dropStmt = pg_strdup(opts->dropStmt);
    newToc->copyStmt = opts->copyStmt ? pg_strdup(opts->copyStmt) : NULL;
 
    if (opts->nDeps > 0)
@@ -3600,7 +3600,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
    }
    else
    {
-       if (te->defn && strlen(te->defn) > 0)
+       if (strlen(te->defn) > 0)
            ahprintf(AH, "%s\n\n", te->defn);
    }
 
@@ -3611,8 +3611,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
     * with DROP commands must appear in one list or the other.
     */
    if (!ropt->noOwner && !ropt->use_setsessauth &&
-       te->owner && strlen(te->owner) > 0 &&
-       te->dropStmt && strlen(te->dropStmt) > 0)
+       strlen(te->owner) > 0 && strlen(te->dropStmt) > 0)
    {
        if (strcmp(te->desc, "AGGREGATE") == 0 ||
            strcmp(te->desc, "BLOB") == 0 ||
index 4d8f499247c3b7d6a30eb92738d32c1b38bf8211..ebf3d209ea18b6d6dd9d2a47b09b9f589b3cffed 100644 (file)
@@ -95,7 +95,12 @@ typedef z_stream *z_streamp;
 #define K_VERS_1_13 MAKE_ARCHIVE_VERSION(1, 13, 0) /* change search_path
                                                     * behavior */
 
-/* Current archive version number (the format we can output) */
+/*
+ * Current archive version number (the format we can output)
+ *
+ * Note: If you update the current archive version, consider
+ * https://postgr.es/m/[email protected]
+ */
 #define K_VERS_MAJOR 1
 #define K_VERS_MINOR 13
 #define K_VERS_REV 0
index a08bc4ecaec0faa1b9e451838d5af6eeede70dcd..a1bcf62b85737262817ca03c32e08fbbf6287cde 100644 (file)
@@ -2165,6 +2165,8 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo)
                                       .owner = tbinfo->rolname,
                                       .description = "TABLE DATA",
                                       .section = SECTION_DATA,
+                                      .createStmt = "",
+                                      .dropStmt = "",
                                       .copyStmt = copyStmt,
                                       .deps = &(tbinfo->dobj.dumpId),
                                       .nDeps = 1,
@@ -2219,6 +2221,7 @@ refreshMatViewData(Archive *fout, TableDataInfo *tdinfo)
                                  .description = "MATERIALIZED VIEW DATA",
                                  .section = SECTION_POST_DATA,
                                  .createStmt = q->data,
+                                 .dropStmt = "",
                                  .deps = tdinfo->dobj.dependencies,
                                  .nDeps = tdinfo->dobj.nDeps));
 
@@ -2784,6 +2787,7 @@ dumpDatabase(Archive *fout)
                                      .description = "COMMENT",
                                      .section = SECTION_NONE,
                                      .createStmt = dbQry->data,
+                                     .dropStmt = "",
                                      .deps = &dbDumpId,
                                      .nDeps = 1));
        }
@@ -2813,6 +2817,7 @@ dumpDatabase(Archive *fout)
                                      .description = "SECURITY LABEL",
                                      .section = SECTION_NONE,
                                      .createStmt = seclabelQry->data,
+                                     .dropStmt = "",
                                      .deps = &dbDumpId,
                                      .nDeps = 1));
        destroyPQExpBuffer(seclabelQry);
@@ -2929,8 +2934,10 @@ dumpDatabase(Archive *fout)
        ArchiveEntry(fout, nilCatalogId, createDumpId(),
                     ARCHIVE_OPTS(.tag = "pg_largeobject",
                                  .description = "pg_largeobject",
+                                 .owner = "",
                                  .section = SECTION_PRE_DATA,
-                                 .createStmt = loOutQry->data));
+                                 .createStmt = loOutQry->data,
+                                 .dropStmt = ""));
 
        PQclear(lo_res);
 
@@ -3038,8 +3045,10 @@ dumpEncoding(Archive *AH)
    ArchiveEntry(AH, nilCatalogId, createDumpId(),
                 ARCHIVE_OPTS(.tag = "ENCODING",
                              .description = "ENCODING",
+                             .owner = "",
                              .section = SECTION_PRE_DATA,
-                             .createStmt = qry->data));
+                             .createStmt = qry->data,
+                             .dropStmt = ""));
 
    destroyPQExpBuffer(qry);
 }
@@ -3064,8 +3073,10 @@ dumpStdStrings(Archive *AH)
    ArchiveEntry(AH, nilCatalogId, createDumpId(),
                 ARCHIVE_OPTS(.tag = "STDSTRINGS",
                              .description = "STDSTRINGS",
+                             .owner = "",
                              .section = SECTION_PRE_DATA,
-                             .createStmt = qry->data));
+                             .createStmt = qry->data,
+                             .dropStmt = ""));
 
    destroyPQExpBuffer(qry);
 }
@@ -3119,8 +3130,10 @@ dumpSearchPath(Archive *AH)
    ArchiveEntry(AH, nilCatalogId, createDumpId(),
                 ARCHIVE_OPTS(.tag = "SEARCHPATH",
                              .description = "SEARCHPATH",
+                             .owner = "",
                              .section = SECTION_PRE_DATA,
-                             .createStmt = qry->data));
+                             .createStmt = qry->data,
+                             .dropStmt = ""));
 
    /* Also save it in AH->searchpath, in case we're doing plain text dump */
    AH->searchpath = pg_strdup(qry->data);
@@ -3601,6 +3614,7 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo)
                                      .description = "ROW SECURITY",
                                      .section = SECTION_POST_DATA,
                                      .createStmt = query->data,
+                                     .dropStmt = "",
                                      .deps = &(tbinfo->dobj.dumpId),
                                      .nDeps = 1));
 
@@ -3968,8 +3982,10 @@ dumpPublicationTable(Archive *fout, PublicationRelInfo *pubrinfo)
                 ARCHIVE_OPTS(.tag = tag,
                              .namespace = tbinfo->dobj.namespace->dobj.name,
                              .description = "PUBLICATION TABLE",
+                             .owner = "",
                              .section = SECTION_POST_DATA,
-                             .createStmt = query->data));
+                             .createStmt = query->data,
+                             .dropStmt = ""));
 
    free(tag);
    destroyPQExpBuffer(query);
@@ -9393,6 +9409,7 @@ dumpComment(Archive *fout, const char *type, const char *name,
                                  .description = "COMMENT",
                                  .section = SECTION_NONE,
                                  .createStmt = query->data,
+                                 .dropStmt = "",
                                  .deps = &dumpId,
                                  .nDeps = 1));
 
@@ -9462,6 +9479,7 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
                                      .description = "COMMENT",
                                      .section = SECTION_NONE,
                                      .createStmt = query->data,
+                                     .dropStmt = "",
                                      .deps = &(tbinfo->dobj.dumpId),
                                      .nDeps = 1));
        }
@@ -9487,6 +9505,7 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
                                      .description = "COMMENT",
                                      .section = SECTION_NONE,
                                      .createStmt = query->data,
+                                     .dropStmt = "",
                                      .deps = &(tbinfo->dobj.dumpId),
                                      .nDeps = 1));
        }
@@ -9767,8 +9786,11 @@ dumpDumpableObject(Archive *fout, DumpableObject *dobj)
                te = ArchiveEntry(fout, dobj->catId, dobj->dumpId,
                                  ARCHIVE_OPTS(.tag = dobj->name,
                                               .description = "BLOBS",
+                                              .owner = "",
                                               .section = SECTION_DATA,
-                                              .dumpFn = dumpBlobs));
+                                              .dumpFn = dumpBlobs,
+                                              .createStmt = "",
+                                              .dropStmt = ""));
 
                /*
                 * Set the TocEntry's dataLength in case we are doing a
@@ -9973,6 +9995,7 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
        ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId,
                     ARCHIVE_OPTS(.tag = extinfo->dobj.name,
                                  .description = "EXTENSION",
+                                 .owner = "",
                                  .section = SECTION_PRE_DATA,
                                  .createStmt = q->data,
                                  .dropStmt = delq->data));
@@ -11116,6 +11139,7 @@ dumpCompositeTypeColComments(Archive *fout, TypeInfo *tyinfo)
                                      .description = "COMMENT",
                                      .section = SECTION_NONE,
                                      .createStmt = query->data,
+                                     .dropStmt = "",
                                      .deps = &(tyinfo->dobj.dumpId),
                                      .nDeps = 1));
        }
@@ -11171,7 +11195,8 @@ dumpShellType(Archive *fout, ShellTypeInfo *stinfo)
                                  .owner = stinfo->baseType->rolname,
                                  .description = "SHELL TYPE",
                                  .section = SECTION_PRE_DATA,
-                                 .createStmt = q->data));
+                                 .createStmt = q->data,
+                                 .dropStmt = ""));
 
    destroyPQExpBuffer(q);
 }
@@ -12116,6 +12141,7 @@ dumpCast(Archive *fout, CastInfo *cast)
        ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
                     ARCHIVE_OPTS(.tag = labelq->data,
                                  .description = "CAST",
+                                 .owner = "",
                                  .section = SECTION_PRE_DATA,
                                  .createStmt = defqry->data,
                                  .dropStmt = delqry->data));
@@ -12243,6 +12269,7 @@ dumpTransform(Archive *fout, TransformInfo *transform)
        ArchiveEntry(fout, transform->dobj.catId, transform->dobj.dumpId,
                     ARCHIVE_OPTS(.tag = labelq->data,
                                  .description = "TRANSFORM",
+                                 .owner = "",
                                  .section = SECTION_PRE_DATA,
                                  .createStmt = defqry->data,
                                  .dropStmt = delqry->data,
@@ -12626,6 +12653,7 @@ dumpAccessMethod(Archive *fout, AccessMethodInfo *aminfo)
        ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
                     ARCHIVE_OPTS(.tag = aminfo->dobj.name,
                                  .description = "ACCESS METHOD",
+                                 .owner = "",
                                  .section = SECTION_PRE_DATA,
                                  .createStmt = q->data,
                                  .dropStmt = delq->data));
@@ -14077,6 +14105,7 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
                     ARCHIVE_OPTS(.tag = prsinfo->dobj.name,
                                  .namespace = prsinfo->dobj.namespace->dobj.name,
                                  .description = "TEXT SEARCH PARSER",
+                                 .owner = "",
                                  .section = SECTION_PRE_DATA,
                                  .createStmt = q->data,
                                  .dropStmt = delq->data));
@@ -14215,6 +14244,7 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
                     ARCHIVE_OPTS(.tag = tmplinfo->dobj.name,
                                  .namespace = tmplinfo->dobj.namespace->dobj.name,
                                  .description = "TEXT SEARCH TEMPLATE",
+                                 .owner = "",
                                  .section = SECTION_PRE_DATA,
                                  .createStmt = q->data,
                                  .dropStmt = delq->data));
@@ -14684,7 +14714,8 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
                                  .owner = daclinfo->defaclrole,
                                  .description = "DEFAULT ACL",
                                  .section = SECTION_POST_DATA,
-                                 .createStmt = q->data));
+                                 .createStmt = q->data,
+                                 .dropStmt = ""));
 
    destroyPQExpBuffer(tag);
    destroyPQExpBuffer(q);
@@ -14782,6 +14813,7 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
                                  .description = "ACL",
                                  .section = SECTION_NONE,
                                  .createStmt = sql->data,
+                                 .dropStmt = "",
                                  .deps = &objDumpId,
                                  .nDeps = 1));
        destroyPQExpBuffer(tag);
@@ -14871,6 +14903,7 @@ dumpSecLabel(Archive *fout, const char *type, const char *name,
                                  .description = "SECURITY LABEL",
                                  .section = SECTION_NONE,
                                  .createStmt = query->data,
+                                 .dropStmt = "",
                                  .deps = &dumpId,
                                  .nDeps = 1));
        destroyPQExpBuffer(tag);
@@ -14954,6 +14987,7 @@ dumpTableSecLabel(Archive *fout, TableInfo *tbinfo, const char *reltypename)
                                  .description = "SECURITY LABEL",
                                  .section = SECTION_NONE,
                                  .createStmt = query->data,
+                                 .dropStmt = "",
                                  .deps = &(tbinfo->dobj.dumpId),
                                  .nDeps = 1));
    }
@@ -16313,8 +16347,10 @@ dumpIndexAttach(Archive *fout, IndexAttachInfo *attachinfo)
                     ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
                                  .namespace = attachinfo->dobj.namespace->dobj.name,
                                  .description = "INDEX ATTACH",
+                                 .owner = "",
                                  .section = SECTION_POST_DATA,
-                                 .createStmt = q->data));
+                                 .createStmt = q->data,
+                                 .dropStmt = ""));
 
        destroyPQExpBuffer(q);
    }
@@ -16944,6 +16980,7 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
                                          .description = "SEQUENCE OWNED BY",
                                          .section = SECTION_PRE_DATA,
                                          .createStmt = query->data,
+                                         .dropStmt = "",
                                          .deps = &(tbinfo->dobj.dumpId),
                                          .nDeps = 1));
        }
@@ -17012,6 +17049,7 @@ dumpSequenceData(Archive *fout, TableDataInfo *tdinfo)
                                  .description = "SEQUENCE SET",
                                  .section = SECTION_DATA,
                                  .createStmt = query->data,
+                                 .dropStmt = "",
                                  .deps = &(tbinfo->dobj.dumpId),
                                  .nDeps = 1));