]> granicus.if.org Git - postgresql/commitdiff
Improve pg_dump/pg_restore --create --if-exists logic.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 17 Nov 2016 19:59:19 +0000 (14:59 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 17 Nov 2016 19:59:19 +0000 (14:59 -0500)
Teach it not to complain if the dropStmt attached to an archive entry
is actually spelled CREATE OR REPLACE VIEW, since that will happen due to
an upcoming bug fix.  Also, if it doesn't recognize a dropStmt, have it
print a WARNING and then emit the dropStmt unmodified.  That seems like a
much saner behavior than Assert'ing or dumping core due to a null-pointer
dereference, which is what would happen before :-(.

Back-patch to 9.4 where this option was introduced.

Discussion: <19092.1479325184@sss.pgh.pa.us>

src/bin/pg_dump/pg_backup_archiver.c

index 05bdbdbf02a75357733c4b9c7e2e7b620488001a..9e9d11681aa0263fa682b4f9c37349677474a495 100644 (file)
@@ -515,7 +515,6 @@ RestoreArchive(Archive *AHX)
                                                 * knows how to do it, without depending on
                                                 * te->dropStmt; use that.  For other objects we need
                                                 * to parse the command.
-                                                *
                                                 */
                                                if (strncmp(te->desc, "BLOB", 4) == 0)
                                                {
@@ -523,10 +522,8 @@ RestoreArchive(Archive *AHX)
                                                }
                                                else
                                                {
-                                                       char            buffer[40];
-                                                       char       *mark;
                                                        char       *dropStmt = pg_strdup(te->dropStmt);
-                                                       char       *dropStmtPtr = dropStmt;
+                                                       char       *dropStmtOrig = dropStmt;
                                                        PQExpBuffer ftStmt = createPQExpBuffer();
 
                                                        /*
@@ -543,18 +540,28 @@ RestoreArchive(Archive *AHX)
                                                        /*
                                                         * ALTER TABLE..ALTER COLUMN..DROP DEFAULT does
                                                         * not support the IF EXISTS clause, and therefore
-                                                        * we simply emit the original command for such
-                                                        * objects. For other objects, we need to extract
-                                                        * the first part of the DROP which includes the
-                                                        * object type. Most of the time this matches
+                                                        * we simply emit the original command for DEFAULT
+                                                        * objects (modulo the adjustment made above).
+                                                        *
+                                                        * If we used CREATE OR REPLACE VIEW as a means of
+                                                        * quasi-dropping an ON SELECT rule, that should
+                                                        * be emitted unchanged as well.
+                                                        *
+                                                        * For other object types, we need to extract the
+                                                        * first part of the DROP which includes the
+                                                        * object type.  Most of the time this matches
                                                         * te->desc, so search for that; however for the
                                                         * different kinds of CONSTRAINTs, we know to
                                                         * search for hardcoded "DROP CONSTRAINT" instead.
                                                         */
-                                                       if (strcmp(te->desc, "DEFAULT") == 0)
+                                                       if (strcmp(te->desc, "DEFAULT") == 0 ||
+                                                               strncmp(dropStmt, "CREATE OR REPLACE VIEW", 22) == 0)
                                                                appendPQExpBufferStr(ftStmt, dropStmt);
                                                        else
                                                        {
+                                                               char            buffer[40];
+                                                               char       *mark;
+
                                                                if (strcmp(te->desc, "CONSTRAINT") == 0 ||
                                                                 strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
                                                                        strcmp(te->desc, "FK CONSTRAINT") == 0)
@@ -564,19 +571,28 @@ RestoreArchive(Archive *AHX)
                                                                                         te->desc);
 
                                                                mark = strstr(dropStmt, buffer);
-                                                               Assert(mark != NULL);
 
-                                                               *mark = '\0';
-                                                               appendPQExpBuffer(ftStmt, "%s%s IF EXISTS%s",
-                                                                                                 dropStmt, buffer,
-                                                                                                 mark + strlen(buffer));
+                                                               if (mark)
+                                                               {
+                                                                       *mark = '\0';
+                                                                       appendPQExpBuffer(ftStmt, "%s%s IF EXISTS%s",
+                                                                                                         dropStmt, buffer,
+                                                                                                         mark + strlen(buffer));
+                                                               }
+                                                               else
+                                                               {
+                                                                       /* complain and emit unmodified command */
+                                                                       write_msg(modulename,
+                                                                                         "WARNING: could not find where to insert IF EXISTS in statement \"%s\"\n",
+                                                                                         dropStmtOrig);
+                                                                       appendPQExpBufferStr(ftStmt, dropStmt);
+                                                               }
                                                        }
 
                                                        ahprintf(AH, "%s", ftStmt->data);
 
                                                        destroyPQExpBuffer(ftStmt);
-
-                                                       pg_free(dropStmtPtr);
+                                                       pg_free(dropStmtOrig);
                                                }
                                        }
                                }