mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-09 08:10:09 +08:00
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>
This commit is contained in:
parent
fcf70e0dbc
commit
ac888986fc
@ -521,7 +521,6 @@ RestoreArchive(Archive *AHX)
|
|||||||
* knows how to do it, without depending on
|
* knows how to do it, without depending on
|
||||||
* te->dropStmt; use that. For other objects we need
|
* te->dropStmt; use that. For other objects we need
|
||||||
* to parse the command.
|
* to parse the command.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
if (strncmp(te->desc, "BLOB", 4) == 0)
|
if (strncmp(te->desc, "BLOB", 4) == 0)
|
||||||
{
|
{
|
||||||
@ -529,10 +528,8 @@ RestoreArchive(Archive *AHX)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char buffer[40];
|
|
||||||
char *mark;
|
|
||||||
char *dropStmt = pg_strdup(te->dropStmt);
|
char *dropStmt = pg_strdup(te->dropStmt);
|
||||||
char *dropStmtPtr = dropStmt;
|
char *dropStmtOrig = dropStmt;
|
||||||
PQExpBuffer ftStmt = createPQExpBuffer();
|
PQExpBuffer ftStmt = createPQExpBuffer();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -549,18 +546,28 @@ RestoreArchive(Archive *AHX)
|
|||||||
/*
|
/*
|
||||||
* ALTER TABLE..ALTER COLUMN..DROP DEFAULT does
|
* ALTER TABLE..ALTER COLUMN..DROP DEFAULT does
|
||||||
* not support the IF EXISTS clause, and therefore
|
* not support the IF EXISTS clause, and therefore
|
||||||
* we simply emit the original command for such
|
* we simply emit the original command for DEFAULT
|
||||||
* objects. For other objects, we need to extract
|
* objects (modulo the adjustment made above).
|
||||||
* the first part of the DROP which includes the
|
*
|
||||||
* object type. Most of the time this matches
|
* 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
|
* te->desc, so search for that; however for the
|
||||||
* different kinds of CONSTRAINTs, we know to
|
* different kinds of CONSTRAINTs, we know to
|
||||||
* search for hardcoded "DROP CONSTRAINT" instead.
|
* 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);
|
appendPQExpBufferStr(ftStmt, dropStmt);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
char buffer[40];
|
||||||
|
char *mark;
|
||||||
|
|
||||||
if (strcmp(te->desc, "CONSTRAINT") == 0 ||
|
if (strcmp(te->desc, "CONSTRAINT") == 0 ||
|
||||||
strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
|
strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
|
||||||
strcmp(te->desc, "FK CONSTRAINT") == 0)
|
strcmp(te->desc, "FK CONSTRAINT") == 0)
|
||||||
@ -570,19 +577,28 @@ RestoreArchive(Archive *AHX)
|
|||||||
te->desc);
|
te->desc);
|
||||||
|
|
||||||
mark = strstr(dropStmt, buffer);
|
mark = strstr(dropStmt, buffer);
|
||||||
Assert(mark != NULL);
|
|
||||||
|
|
||||||
*mark = '\0';
|
if (mark)
|
||||||
appendPQExpBuffer(ftStmt, "%s%s IF EXISTS%s",
|
{
|
||||||
dropStmt, buffer,
|
*mark = '\0';
|
||||||
mark + strlen(buffer));
|
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);
|
ahprintf(AH, "%s", ftStmt->data);
|
||||||
|
|
||||||
destroyPQExpBuffer(ftStmt);
|
destroyPQExpBuffer(ftStmt);
|
||||||
|
pg_free(dropStmtOrig);
|
||||||
pg_free(dropStmtPtr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user