Skip to content

Commit a786403

Browse files
committed
Improve pg_dump/pg_restore --create --if-exists logic.
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>
1 parent c0db1ec commit a786403

File tree

1 file changed

+32
-16
lines changed

1 file changed

+32
-16
lines changed

src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -506,18 +506,15 @@ RestoreArchive(Archive *AHX)
506506
* knows how to do it, without depending on
507507
* te->dropStmt; use that. For other objects we need
508508
* to parse the command.
509-
*
510509
*/
511510
if (strncmp(te->desc, "BLOB", 4) == 0)
512511
{
513512
DropBlobIfExists(AH, te->catalogId.oid);
514513
}
515514
else
516515
{
517-
char buffer[40];
518-
char *mark;
519516
char *dropStmt = pg_strdup(te->dropStmt);
520-
char *dropStmtPtr = dropStmt;
517+
char *dropStmtOrig = dropStmt;
521518
PQExpBuffer ftStmt = createPQExpBuffer();
522519

523520
/*
@@ -534,18 +531,28 @@ RestoreArchive(Archive *AHX)
534531
/*
535532
* ALTER TABLE..ALTER COLUMN..DROP DEFAULT does
536533
* not support the IF EXISTS clause, and therefore
537-
* we simply emit the original command for such
538-
* objects. For other objects, we need to extract
539-
* the first part of the DROP which includes the
540-
* object type. Most of the time this matches
534+
* we simply emit the original command for DEFAULT
535+
* objects (modulo the adjustment made above).
536+
*
537+
* If we used CREATE OR REPLACE VIEW as a means of
538+
* quasi-dropping an ON SELECT rule, that should
539+
* be emitted unchanged as well.
540+
*
541+
* For other object types, we need to extract the
542+
* first part of the DROP which includes the
543+
* object type. Most of the time this matches
541544
* te->desc, so search for that; however for the
542545
* different kinds of CONSTRAINTs, we know to
543546
* search for hardcoded "DROP CONSTRAINT" instead.
544547
*/
545-
if (strcmp(te->desc, "DEFAULT") == 0)
548+
if (strcmp(te->desc, "DEFAULT") == 0 ||
549+
strncmp(dropStmt, "CREATE OR REPLACE VIEW", 22) == 0)
546550
appendPQExpBufferStr(ftStmt, dropStmt);
547551
else
548552
{
553+
char buffer[40];
554+
char *mark;
555+
549556
if (strcmp(te->desc, "CONSTRAINT") == 0 ||
550557
strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
551558
strcmp(te->desc, "FK CONSTRAINT") == 0)
@@ -555,19 +562,28 @@ RestoreArchive(Archive *AHX)
555562
te->desc);
556563

557564
mark = strstr(dropStmt, buffer);
558-
Assert(mark != NULL);
559565

560-
*mark = '\0';
561-
appendPQExpBuffer(ftStmt, "%s%s IF EXISTS%s",
562-
dropStmt, buffer,
563-
mark + strlen(buffer));
566+
if (mark)
567+
{
568+
*mark = '\0';
569+
appendPQExpBuffer(ftStmt, "%s%s IF EXISTS%s",
570+
dropStmt, buffer,
571+
mark + strlen(buffer));
572+
}
573+
else
574+
{
575+
/* complain and emit unmodified command */
576+
write_msg(modulename,
577+
"WARNING: could not find where to insert IF EXISTS in statement \"%s\"\n",
578+
dropStmtOrig);
579+
appendPQExpBufferStr(ftStmt, dropStmt);
580+
}
564581
}
565582

566583
ahprintf(AH, "%s", ftStmt->data);
567584

568585
destroyPQExpBuffer(ftStmt);
569-
570-
pg_free(dropStmtPtr);
586+
pg_free(dropStmtOrig);
571587
}
572588
}
573589
}

0 commit comments

Comments
 (0)