From fd02931a6c83bf3beb2d03f65700600787d569a3 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Tue, 30 Sep 2014 12:06:37 -0300 Subject: [PATCH] Fix pg_dump's --if-exists for large objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 | 103 +++++++++++++++------------ 1 file changed, 59 insertions(+), 44 deletions(-) diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index 32a08b038b..1303ef6d49 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -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); + + destroyPQExpBuffer(ftStmt); + + pg_free(dropStmtPtr); } - - ahprintf(AH, "%s", ftStmt->data); - - destroyPQExpBuffer(ftStmt); - - pg_free(dropStmtPtr); } } }