Fix pg_dump's --if-exists for large objects
authorAlvaro Herrera
Tue, 30 Sep 2014 15:06:37 +0000 (12:06 -0300)
committerAlvaro Herrera
Tue, 30 Sep 2014 15:06:37 +0000 (12:06 -0300)
This was born broken in 9067310cc5dd590e36c2c3219dbf3961d7c9f8cb.

Per trouble report from Joachim Wieland.

Pavel Stěhule and Álvaro Herrera

src/bin/pg_dump/pg_backup_archiver.c

index 32a08b038b071d995551d81765b9e62923b3e65b..1303ef6d49b1246ef099ee3a25b3eb38571337b6 100644 (file)
@@ -440,60 +440,75 @@ RestoreArchive(Archive *AHX)
                    }
                    else
                    {
-                       char        buffer[40];
-                       char       *mark;
-                       char       *dropStmt = pg_strdup(te->dropStmt);
-                       char       *dropStmtPtr = dropStmt;
-                       PQExpBuffer ftStmt = createPQExpBuffer();
-
                        /*
-                        * Need to inject IF EXISTS clause after ALTER TABLE
-                        * part in ALTER TABLE .. DROP statement
+                        * Inject an appropriate spelling of "if exists".  For
+                        * large objects, we have a separate routine that
+                        * knows how to do it, without depending on
+                        * te->dropStmt; use that.  For other objects we need
+                        * to parse the command.
+                        *
                         */
-                       if (strncmp(dropStmt, "ALTER TABLE", 11) == 0)
+                       if (strncmp(te->desc, "BLOB", 4) == 0)
                        {
-                           appendPQExpBuffer(ftStmt,
-                                             "ALTER TABLE IF EXISTS");
-                           dropStmt = dropStmt + 11;
+                           DropBlobIfExists(AH, te->catalogId.oid);
                        }
-
-                       /*
-                        * 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 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)
-                           appendPQExpBuffer(ftStmt, "%s", dropStmt);
                        else
                        {
-                           if (strcmp(te->desc, "CONSTRAINT") == 0 ||
-                               strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
-                               strcmp(te->desc, "FK CONSTRAINT") == 0)
-                               strcpy(buffer, "DROP CONSTRAINT");
+                           char        buffer[40];
+                           char       *mark;
+                           char       *dropStmt = pg_strdup(te->dropStmt);
+                           char       *dropStmtPtr = dropStmt;
+                           PQExpBuffer ftStmt = createPQExpBuffer();
+
+                           /*
+                            * Need to inject IF EXISTS clause after ALTER
+                            * TABLE part in ALTER TABLE .. DROP statement
+                            */
+                           if (strncmp(dropStmt, "ALTER TABLE", 11) == 0)
+                           {
+                               appendPQExpBuffer(ftStmt,
+                                                 "ALTER TABLE IF EXISTS");
+                               dropStmt = dropStmt + 11;
+                           }
+
+                           /*
+                            * 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
+                            * 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)
+                               appendPQExpBuffer(ftStmt, "%s", dropStmt);
                            else
-                               snprintf(buffer, sizeof(buffer), "DROP %s",
-                                        te->desc);
+                           {
+                               if (strcmp(te->desc, "CONSTRAINT") == 0 ||
+                                strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
+                                   strcmp(te->desc, "FK CONSTRAINT") == 0)
+                                   strcpy(buffer, "DROP CONSTRAINT");
+                               else
+                                   snprintf(buffer, sizeof(buffer), "DROP %s",
+                                            te->desc);
 
-                           mark = strstr(dropStmt, buffer);
-                           Assert(mark != NULL);
+                               mark = strstr(dropStmt, buffer);
+                               Assert(mark != NULL);
 
-                           *mark = '\0';
-                           appendPQExpBuffer(ftStmt, "%s%s IF EXISTS%s",
-                                             dropStmt, buffer,
-                                             mark + strlen(buffer));
-                       }
+                               *mark = '\0';
+                               appendPQExpBuffer(ftStmt, "%s%s IF EXISTS%s",
+                                                 dropStmt, buffer,
+                                                 mark + strlen(buffer));
+                           }
 
-                       ahprintf(AH, "%s", ftStmt->data);
+                           ahprintf(AH, "%s", ftStmt->data);
 
-                       destroyPQExpBuffer(ftStmt);
+                           destroyPQExpBuffer(ftStmt);
 
-                       pg_free(dropStmtPtr);
+                           pg_free(dropStmtPtr);
+                       }
                    }
                }
            }