diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml
index 1ed5e4f..f64c4ba 100644
--- a/doc/src/sgml/ref/pg_dump.sgml
+++ b/doc/src/sgml/ref/pg_dump.sgml
@@ -650,6 +650,16 @@ PostgreSQL documentation
+
+
+
+ It use conditional commands (with IF EXISTS
+ clause) for cleaning database schema.
+
+
+
+
+
diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml
index 5c6a101..7e5134e 100644
--- a/doc/src/sgml/ref/pg_dumpall.sgml
+++ b/doc/src/sgml/ref/pg_dumpall.sgml
@@ -270,6 +270,16 @@ PostgreSQL documentation
+
+
+
+ It use conditional commands (with IF EXISTS
+ clause) for cleaning database schema.
+
+
+
+
+
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
index b456f95..a4c203a 100644
--- a/src/bin/pg_dump/pg_backup.h
+++ b/src/bin/pg_dump/pg_backup.h
@@ -113,6 +113,7 @@ typedef struct _restoreOptions
char *superuser; /* Username to use as superuser */
char *use_role; /* Issue SET ROLE to this */
int dropSchema;
+ int if_exists;
const char *filename;
int dataOnly;
int schemaOnly;
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index cd7669b..7818fe7 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -54,8 +54,9 @@ static const char *modulename = gettext_noop("archiver");
static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
const int compression, ArchiveMode mode, SetupWorkerPtr setupWorkerPtr);
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te,
- ArchiveHandle *AH);
-static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass);
+ ArchiveHandle *AH, bool if_exists);
+static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt,
+ bool isData, bool acl_pass);
static char *replace_line_endings(const char *str);
static void _doSetFixedOutputState(ArchiveHandle *AH);
static void _doSetSessionAuth(ArchiveHandle *AH, const char *user);
@@ -234,6 +235,7 @@ RestoreArchive(Archive *AHX)
bool parallel_mode;
TocEntry *te;
OutputContext sav;
+
AH->stage = STAGE_INITIALIZING;
@@ -2886,7 +2888,7 @@ _selectTablespace(ArchiveHandle *AH, const char *tablespace)
* information used is all that's available in older dump files.
*/
static void
-_getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
+_getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH, bool if_exists)
{
const char *type = te->desc;
@@ -2953,9 +2955,36 @@ _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
strcmp(type, "OPERATOR CLASS") == 0 ||
strcmp(type, "OPERATOR FAMILY") == 0)
{
- /* Chop "DROP " off the front and make a modifiable copy */
- char *first = pg_strdup(te->dropStmt + 5);
- char *last;
+ char *first;
+ char *last;
+
+ if (!if_exists)
+ {
+ /* just chop first 5 chars - "DROP", and create a modifiable copy */
+ first = pg_strdup(te->dropStmt + 5);
+ }
+ else
+ {
+ char buffer[40];
+ size_t l;
+
+ /* IF EXISTS clause should be optional, check it*/
+ snprintf(buffer, sizeof(buffer), "DROP %s%s", type,
+ if_exists ? " IF EXISTS" : "");
+ l = strlen(buffer);
+
+ if (strncmp(te->dropStmt, buffer, l) == 0)
+ {
+ /* append command type to target type */
+ appendPQExpBufferStr(buf, type);
+
+ /* skip first n chars, and create a modifieble copy */
+ first = pg_strdup(te->dropStmt + l);
+ }
+ else
+ /* IF EXISTS clause was not used, simple solution */
+ first = pg_strdup(te->dropStmt + 5);
+ }
/* point to last character in string */
last = first + strlen(first) - 1;
@@ -2976,8 +3005,11 @@ _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
}
static void
-_printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass)
+_printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData,
+ bool acl_pass)
{
+ int if_exists = ropt->if_exists;
+
/* ACLs are dumped only during acl pass */
if (acl_pass)
{
@@ -3135,7 +3167,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
PQExpBuffer temp = createPQExpBuffer();
appendPQExpBuffer(temp, "ALTER ");
- _getObjectDescription(temp, te, AH);
+ _getObjectDescription(temp, te, AH, if_exists);
appendPQExpBuffer(temp, " OWNER TO %s;", fmtId(te->owner));
ahprintf(AH, "%s\n\n", temp->data);
destroyPQExpBuffer(temp);
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index becc82b..d6036d1 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -140,6 +140,7 @@ static int no_security_labels = 0;
static int no_synchronized_snapshots = 0;
static int no_unlogged_table_data = 0;
static int serializable_deferrable = 0;
+static int if_exists = 0;
static void help(const char *progname);
@@ -345,6 +346,7 @@ main(int argc, char **argv)
{"attribute-inserts", no_argument, &column_inserts, 1},
{"binary-upgrade", no_argument, &binary_upgrade, 1},
{"column-inserts", no_argument, &column_inserts, 1},
+ {"if-exists", no_argument, &if_exists, 1},
{"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
{"disable-triggers", no_argument, &disable_triggers, 1},
{"exclude-table-data", required_argument, NULL, 4},
@@ -576,6 +578,9 @@ main(int argc, char **argv)
exit_nicely(1);
}
+ if (if_exists && !outputClean)
+ exit_horribly(NULL, "option --if-exists requires -c/--clean option\n");
+
/* Identify archive format to emit */
archiveFormat = parseArchiveFormat(format, &archiveMode);
@@ -808,6 +813,7 @@ main(int argc, char **argv)
ropt->dropSchema = outputClean;
ropt->dataOnly = dataOnly;
ropt->schemaOnly = schemaOnly;
+ ropt->if_exists = if_exists;
ropt->dumpSections = dumpSections;
ropt->aclsSkip = aclsSkip;
ropt->superuser = outputSuperuser;
@@ -886,6 +892,7 @@ help(const char *progname)
printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
printf(_(" --binary-upgrade for use by upgrade utilities only\n"));
printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
+ printf(_(" --if-exists use IF EXISTS when dropping objects\n"));
printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
printf(_(" --disable-triggers disable triggers during data-only restore\n"));
printf(_(" --exclude-table-data=TABLE do NOT dump data for the named table(s)\n"));
@@ -2262,7 +2269,8 @@ dumpDatabase(Archive *fout)
}
- appendPQExpBuffer(delQry, "DROP DATABASE %s;\n",
+ appendPQExpBuffer(delQry, "DROP DATABASE %s%s;\n",
+ if_exists ? "IF EXISTS " : "",
fmtId(datname));
dbDumpId = createDumpId();
@@ -7781,7 +7789,9 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
qnspname = pg_strdup(fmtId(nspinfo->dobj.name));
- appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
+ appendPQExpBuffer(delq, "DROP SCHEMA %s%s;\n",
+ if_exists ? "IF EXISTS " : "",
+ qnspname);
appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
@@ -7840,7 +7850,9 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
qextname = pg_strdup(fmtId(extinfo->dobj.name));
- appendPQExpBuffer(delq, "DROP EXTENSION %s;\n", qextname);
+ appendPQExpBuffer(delq, "DROP EXTENSION %s%s;\n",
+ if_exists ? "IF EXISTS " : "",
+ qextname);
if (!binary_upgrade)
{
@@ -8014,7 +8026,8 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
* CASCADE shouldn't be required here as for normal types since the I/O
* functions are generic and do not get dropped.
*/
- appendPQExpBuffer(delq, "DROP TYPE %s.",
+ appendPQExpBuffer(delq, "DROP TYPE %s%s.",
+ if_exists ? "IF EXISTS " : "",
fmtId(tyinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, "%s;\n",
qtypname);
@@ -8144,7 +8157,8 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
* CASCADE shouldn't be required here as for normal types since the I/O
* functions are generic and do not get dropped.
*/
- appendPQExpBuffer(delq, "DROP TYPE %s.",
+ appendPQExpBuffer(delq, "DROP TYPE %s%s.",
+ if_exists ? "IF EXISTS " : "",
fmtId(tyinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, "%s;\n",
qtypname);
@@ -8484,7 +8498,8 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
* the type and its I/O functions makes it impossible to drop the type any
* other way.
*/
- appendPQExpBuffer(delq, "DROP TYPE %s.",
+ appendPQExpBuffer(delq, "DROP TYPE %s%s.",
+ if_exists ? "IF EXISTS " : "",
fmtId(tyinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, "%s CASCADE;\n",
qtypname);
@@ -8744,7 +8759,8 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delq, "DROP DOMAIN %s.",
+ appendPQExpBuffer(delq, "DROP DOMAIN %s%s.",
+ if_exists ? "IF EXISTS " : "",
fmtId(tyinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, "%s;\n",
qtypname);
@@ -8959,7 +8975,8 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delq, "DROP TYPE %s.",
+ appendPQExpBuffer(delq, "DROP TYPE %s%s.",
+ if_exists ? "IF EXISTS " : "",
fmtId(tyinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, "%s;\n",
qtypname);
@@ -9270,7 +9287,8 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
else
lanschema = NULL;
- appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n",
+ appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s%s;\n",
+ if_exists ? "IF EXISTS " : "",
qlanname);
if (useParams)
@@ -9811,7 +9829,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delqry, "DROP FUNCTION %s.%s;\n",
+ appendPQExpBuffer(delqry, "DROP FUNCTION %s%s.%s;\n",
+ if_exists ? "IF EXISTS " : "",
fmtId(finfo->dobj.namespace->dobj.name),
funcsig);
@@ -10029,7 +10048,8 @@ dumpCast(Archive *fout, CastInfo *cast)
delqry = createPQExpBuffer();
labelq = createPQExpBuffer();
- appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
+ appendPQExpBuffer(delqry, "DROP CAST %s(%s AS %s);\n",
+ if_exists ? "IF EXISTS " : "",
getFormattedTypeName(fout, cast->castsource, zeroAsNone),
getFormattedTypeName(fout, cast->casttarget, zeroAsNone));
@@ -10299,7 +10319,8 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delq, "DROP OPERATOR %s.%s;\n",
+ appendPQExpBuffer(delq, "DROP OPERATOR %s%s.%s;\n",
+ if_exists ? "IF EXISTS " : "",
fmtId(oprinfo->dobj.namespace->dobj.name),
oprid->data);
@@ -10585,7 +10606,8 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delq, "DROP OPERATOR CLASS %s",
+ appendPQExpBuffer(delq, "DROP OPERATOR CLASS %s%s",
+ if_exists ? "IF EXISTS " : "",
fmtId(opcinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, ".%s",
fmtId(opcinfo->dobj.name));
@@ -11029,7 +11051,8 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delq, "DROP OPERATOR FAMILY %s",
+ appendPQExpBuffer(delq, "DROP OPERATOR FAMILY %s%s",
+ if_exists ? "IF EXISTS " : "",
fmtId(opfinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, ".%s",
fmtId(opfinfo->dobj.name));
@@ -11203,7 +11226,8 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delq, "DROP COLLATION %s",
+ appendPQExpBuffer(delq, "DROP COLLATION %s%s",
+ if_exists ? "IF EXISTS " : "",
fmtId(collinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, ".%s;\n",
fmtId(collinfo->dobj.name));
@@ -11300,7 +11324,8 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delq, "DROP CONVERSION %s",
+ appendPQExpBuffer(delq, "DROP CONVERSION %s%s",
+ if_exists ? "IF EXISTS " : "",
fmtId(convinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, ".%s;\n",
fmtId(convinfo->dobj.name));
@@ -11544,7 +11569,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
+ appendPQExpBuffer(delq, "DROP AGGREGATE %s%s.%s;\n",
+ if_exists ? "IF EXISTS " : "",
fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
aggsig);
@@ -11643,7 +11669,8 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s",
+ appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s%s",
+ if_exists ? "IF EXISTS " : "",
fmtId(prsinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, ".%s;\n",
fmtId(prsinfo->dobj.name));
@@ -11730,7 +11757,8 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s",
+ appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s%s",
+ if_exists ? "IF EXISTS " : "",
fmtId(dictinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, ".%s;\n",
fmtId(dictinfo->dobj.name));
@@ -11796,7 +11824,8 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s",
+ appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s%s",
+ if_exists ? "IF EXISTS " : "",
fmtId(tmplinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, ".%s;\n",
fmtId(tmplinfo->dobj.name));
@@ -11924,7 +11953,8 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delq, "DROP TEXT SEARCH CONFIGURATION %s",
+ appendPQExpBuffer(delq, "DROP TEXT SEARCH CONFIGURATION %s%s",
+ if_exists ? "IF EXISTS " : "",
fmtId(cfginfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, ".%s;\n",
fmtId(cfginfo->dobj.name));
@@ -12000,7 +12030,8 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
appendPQExpBuffer(q, ";\n");
- appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
+ appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s%s;\n",
+ if_exists ? "IF EXISTS " : "",
qfdwname);
appendPQExpBuffer(labelq, "FOREIGN DATA WRAPPER %s",
@@ -12093,7 +12124,8 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
appendPQExpBuffer(q, ";\n");
- appendPQExpBuffer(delq, "DROP SERVER %s;\n",
+ appendPQExpBuffer(delq, "DROP SERVER %s%s;\n",
+ if_exists ? "IF EXISTS " : "",
qsrvname);
appendPQExpBuffer(labelq, "SERVER %s", qsrvname);
@@ -12211,7 +12243,9 @@ dumpUserMappings(Archive *fout,
appendPQExpBuffer(q, ";\n");
resetPQExpBuffer(delq);
- appendPQExpBuffer(delq, "DROP USER MAPPING FOR %s", fmtId(usename));
+ appendPQExpBuffer(delq, "DROP USER MAPPING %sFOR %s",
+ if_exists ? "IF EXISTS " : "",
+ fmtId(usename));
appendPQExpBuffer(delq, " SERVER %s;\n", fmtId(servername));
resetPQExpBuffer(tag);
@@ -12820,7 +12854,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
* DROP must be fully qualified in case same name appears in
* pg_catalog
*/
- appendPQExpBuffer(delq, "DROP VIEW %s.",
+ appendPQExpBuffer(delq, "DROP VIEW %s%s.",
+ if_exists ? "IF EXISTS " : "",
fmtId(tbinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, "%s;\n",
fmtId(tbinfo->dobj.name));
@@ -12893,7 +12928,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
* DROP must be fully qualified in case same name appears in
* pg_catalog
*/
- appendPQExpBuffer(delq, "DROP %s %s.", reltypename,
+ appendPQExpBuffer(delq, "DROP %s %s%s.", reltypename,
+ if_exists ? "IF EXISTS " : "",
fmtId(tbinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, "%s;\n",
fmtId(tbinfo->dobj.name));
@@ -13427,7 +13463,8 @@ dumpAttrDef(Archive *fout, AttrDefInfo *adinfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delq, "ALTER TABLE %s.",
+ appendPQExpBuffer(delq, "ALTER TABLE %s%s.",
+ if_exists ? "IF EXISTS " : "",
fmtId(tbinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, "%s ",
fmtId(tbinfo->dobj.name));
@@ -13534,7 +13571,8 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
* DROP must be fully qualified in case same name appears in
* pg_catalog
*/
- appendPQExpBuffer(delq, "DROP INDEX %s.",
+ appendPQExpBuffer(delq, "DROP INDEX %s%s.",
+ if_exists ? "IF EXISTS " : "",
fmtId(tbinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, "%s;\n",
fmtId(indxinfo->dobj.name));
@@ -13655,7 +13693,8 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
* DROP must be fully qualified in case same name appears in
* pg_catalog
*/
- appendPQExpBuffer(delq, "ALTER TABLE ONLY %s.",
+ appendPQExpBuffer(delq, "ALTER TABLE %sONLY %s.",
+ if_exists ? "IF EXISTS " : "",
fmtId(tbinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, "%s ",
fmtId(tbinfo->dobj.name));
@@ -13688,7 +13727,8 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
* DROP must be fully qualified in case same name appears in
* pg_catalog
*/
- appendPQExpBuffer(delq, "ALTER TABLE ONLY %s.",
+ appendPQExpBuffer(delq, "ALTER TABLE %sONLY %s.",
+ if_exists ? "IF EXISTS " : "",
fmtId(tbinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delq, "%s ",
fmtId(tbinfo->dobj.name));
@@ -13957,7 +13997,8 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delqry, "DROP SEQUENCE %s.",
+ appendPQExpBuffer(delqry, "DROP SEQUENCE %s%s.",
+ if_exists ? "IF EXISTS " : "",
fmtId(tbinfo->dobj.namespace->dobj.name));
appendPQExpBuffer(delqry, "%s;\n",
fmtId(tbinfo->dobj.name));
@@ -14145,7 +14186,8 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delqry, "DROP TRIGGER %s ",
+ appendPQExpBuffer(delqry, "DROP TRIGGER %s%s ",
+ if_exists ? "IF EXISTS " : "",
fmtId(tginfo->dobj.name));
appendPQExpBuffer(delqry, "ON %s.",
fmtId(tbinfo->dobj.namespace->dobj.name));
@@ -14485,7 +14527,8 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
/*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
- appendPQExpBuffer(delcmd, "DROP RULE %s ",
+ appendPQExpBuffer(delcmd, "DROP RULE %s%s ",
+ if_exists ? "IF EXISTS " : "",
fmtId(rinfo->dobj.name));
appendPQExpBuffer(delcmd, "ON %s.",
fmtId(tbinfo->dobj.namespace->dobj.name));
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 78f702f..3c5c340 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -71,6 +71,7 @@ static bool verbose = false;
static int binary_upgrade = 0;
static int column_inserts = 0;
+static int if_exists = 0;
static int disable_dollar_quoting = 0;
static int disable_triggers = 0;
static int inserts = 0;
@@ -117,6 +118,7 @@ main(int argc, char *argv[])
{"attribute-inserts", no_argument, &column_inserts, 1},
{"binary-upgrade", no_argument, &binary_upgrade, 1},
{"column-inserts", no_argument, &column_inserts, 1},
+ {"if-exists", no_argument, &if_exists, 1},
{"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
{"disable-triggers", no_argument, &disable_triggers, 1},
{"inserts", no_argument, &inserts, 1},
@@ -348,6 +350,8 @@ main(int argc, char *argv[])
appendPQExpBuffer(pgdumpopts, " --binary-upgrade");
if (column_inserts)
appendPQExpBuffer(pgdumpopts, " --column-inserts");
+ if (if_exists)
+ appendPQExpBuffer(pgdumpopts, " --if-exists");
if (disable_dollar_quoting)
appendPQExpBuffer(pgdumpopts, " --disable-dollar-quoting");
if (disable_triggers)
@@ -559,6 +563,7 @@ help(void)
printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
printf(_(" --binary-upgrade for use by upgrade utilities only\n"));
printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
+ printf(_(" --if-exists don't report error if cleaned object doesn't exist\n"));
printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
printf(_(" --disable-triggers disable triggers during data-only restore\n"));
printf(_(" --inserts dump data as INSERT commands, rather than COPY\n"));