diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c
index 7b954edd381212263ef5b46a6429ef0d41642ba5..7fb323a8b87d832b8ffbb0830afa3724a177c0a4 100644
--- a/src/backend/commands/aggregatecmds.c
+++ b/src/backend/commands/aggregatecmds.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.34 2006/04/15 17:45:33 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.35 2006/06/16 20:23:44 adunstan Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -211,7 +211,21 @@ RemoveAggregate(RemoveFuncStmt *stmt)
 	ObjectAddress object;
 
 	/* Look up function and make sure it's an aggregate */
-	procOid = LookupAggNameTypeNames(aggName, aggArgs, false);
+	procOid = LookupAggNameTypeNames(aggName, aggArgs, stmt->missing_ok);
+	
+	if (!OidIsValid(procOid))
+	{
+		/* we only get here if stmt->missing_ok is true */
+
+		/* XXX might need better message here */
+
+		ereport(NOTICE,
+				(errmsg("aggregate %s does not exist ... skipping",
+					   stmt->name)));
+		
+
+		return;
+	}
 
 	/*
 	 * Find the function tuple, do permissions and validity checks
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 96929a0d6c434ea4e51392b2a78936fbad90826e..b37e2e863243477f577967d709ca24fbaa04283e 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.74 2006/04/15 17:45:34 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.75 2006/06/16 20:23:44 adunstan Exp $
  *
  * DESCRIPTION
  *	  These routines take the parse tree and pick out the
@@ -687,7 +687,16 @@ RemoveFunction(RemoveFuncStmt *stmt)
 	/*
 	 * Find the function, do permissions and validity checks
 	 */
-	funcOid = LookupFuncNameTypeNames(functionName, argTypes, false);
+	funcOid = LookupFuncNameTypeNames(functionName, argTypes, stmt->missing_ok);
+	if (stmt->missing_ok &&!OidIsValid(funcOid)) 
+	{
+		ereport(NOTICE,
+				(errmsg("function %s(%s) does not exist ... skipping",
+						NameListToString(functionName),
+						NameListToString(argTypes))));
+		return;
+	}
+
 
 	tup = SearchSysCache(PROCOID,
 						 ObjectIdGetDatum(funcOid),
@@ -1377,6 +1386,7 @@ DropCast(DropCastStmt *stmt)
 	HeapTuple	tuple;
 	ObjectAddress object;
 
+	/* when dropping a cast, the types must exist even if you use IF EXISTS */
 	sourcetypeid = typenameTypeId(NULL, stmt->sourcetype);
 	targettypeid = typenameTypeId(NULL, stmt->targettype);
 
@@ -1385,11 +1395,23 @@ DropCast(DropCastStmt *stmt)
 						   ObjectIdGetDatum(targettypeid),
 						   0, 0);
 	if (!HeapTupleIsValid(tuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("cast from type %s to type %s does not exist",
-						TypeNameToString(stmt->sourcetype),
-						TypeNameToString(stmt->targettype))));
+	{
+		if (! stmt->missing_ok)
+			ereport(ERROR,
+					(errcode(ERRCODE_UNDEFINED_OBJECT),
+					 errmsg("cast from type %s to type %s does not exist",
+							TypeNameToString(stmt->sourcetype),
+							TypeNameToString(stmt->targettype))));
+		else
+			ereport(NOTICE,
+					 (errmsg("cast from type %s to type %s does not exist ... skipping",
+							TypeNameToString(stmt->sourcetype),
+							TypeNameToString(stmt->targettype))));
+
+		return;
+	}
+
+			
 
 	/* Permission check */
 	if (!pg_type_ownercheck(sourcetypeid, GetUserId())
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 8e67219cc0bff9a14e8453f8a18e8a1863c83a7f..343f5a70cfbaef9850e813cb108e698e7af12b5e 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.45 2006/05/02 22:25:10 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.46 2006/06/16 20:23:44 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -700,21 +700,40 @@ RemoveOpClass(RemoveOpClassStmt *stmt)
 		/* Unqualified opclass name, so search the search path */
 		opcID = OpclassnameGetOpcid(amID, opcname);
 		if (!OidIsValid(opcID))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, stmt->amname)));
+		{
+			if (! stmt -> missing_ok )
+				ereport(ERROR,
+						(errcode(ERRCODE_UNDEFINED_OBJECT),
+						 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
+								opcname, stmt->amname)));
+			else
+				ereport(NOTICE,
+						(errmsg("operator class \"%s\" does not exist for access method \"%s\"",
+								opcname, stmt->amname)));
+			
+			return;
+		}
+ 
 		tuple = SearchSysCache(CLAOID,
 							   ObjectIdGetDatum(opcID),
 							   0, 0, 0);
 	}
 
 	if (!HeapTupleIsValid(tuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-						NameListToString(stmt->opclassname), stmt->amname)));
-
+	{
+  
+		if (! stmt->missing_ok )
+			ereport(ERROR,
+					(errcode(ERRCODE_UNDEFINED_OBJECT),
+					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
+							NameListToString(stmt->opclassname), stmt->amname)));
+		else
+			ereport(NOTICE,
+					(errmsg("operator class \"%s\" does not exist for access method \"%s\"",
+							NameListToString(stmt->opclassname), stmt->amname)));
+		return;
+	}
+	
 	opcID = HeapTupleGetOid(tuple);
 
 	/* Permission check: must own opclass or its namespace */
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index 54f50a84771c892bcb25909d03a3d42362ef6abc..04c91f4509e2111af49201c9de7094dd03523d94 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.30 2006/04/15 17:45:34 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.31 2006/06/16 20:23:44 adunstan Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -213,7 +213,15 @@ RemoveOperator(RemoveFuncStmt *stmt)
 	Assert(list_length(stmt->args) == 2);
 	operOid = LookupOperNameTypeNames(NULL, operatorName,
 									  typeName1, typeName2,
-									  false, -1);
+									  stmt->missing_ok, -1);
+ 
+   if (stmt->missing_ok &&!OidIsValid(operOid) )
+   {
+       ereport(NOTICE,
+               (errmsg("operator %s does not exist ... skipping",
+                       NameListToString(operatorName))));
+       return;
+   }
 
 	tup = SearchSysCache(OPEROID,
 						 ObjectIdGetDatum(operOid),
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 801ccb13ec3ee7358250072c8214fbf715e7554b..e661d45239a419ba795de393c90535545f14a3c7 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/proclang.c,v 1.64 2006/03/05 15:58:24 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/proclang.c,v 1.65 2006/06/16 20:23:44 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -396,9 +396,18 @@ DropProceduralLanguage(DropPLangStmt *stmt)
 							 CStringGetDatum(languageName),
 							 0, 0, 0);
 	if (!HeapTupleIsValid(langTup))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("language \"%s\" does not exist", languageName)));
+	{
+		if (! stmt->missing_ok)
+			ereport(ERROR,
+					(errcode(ERRCODE_UNDEFINED_OBJECT),
+					 errmsg("language \"%s\" does not exist", languageName)));
+		else 
+			ereport(NOTICE,
+					(errmsg("language \"%s\" does not exist ... skipping", 
+							languageName)));
+ 
+		return;
+	}
 
 	object.classId = LanguageRelationId;
 	object.objectId = HeapTupleGetOid(langTup);
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index bafea91dfcb4ad5535e05c758414caa61ab280ef..17dcf9f3a518e8ea920698589d7d91de880dbb8b 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.34 2006/03/29 21:17:38 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.35 2006/06/16 20:23:44 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -403,10 +403,25 @@ DropTableSpace(DropTableSpaceStmt *stmt)
 	tuple = heap_getnext(scandesc, ForwardScanDirection);
 
 	if (!HeapTupleIsValid(tuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("tablespace \"%s\" does not exist",
-						tablespacename)));
+	{
+		if ( ! stmt->missing_ok )
+		{
+			ereport(ERROR,
+					(errcode(ERRCODE_UNDEFINED_OBJECT),
+					 errmsg("tablespace \"%s\" does not exist",
+							tablespacename)));
+		}
+		else
+		{
+			ereport(NOTICE,
+					(errmsg("tablespace \"%s\" does not exist ... skipping",
+							tablespacename)));
+			/* XXX I assume I need one or both of these next two calls */
+			heap_endscan(scandesc);
+			heap_close(rel, NoLock);
+		}
+		return;
+	}
 
 	tablespaceoid = HeapTupleGetOid(tuple);
 
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 04cd75e99fb57aeb491294a971f72981abfbf8cb..2de745682772f90855937953e71af9614dca04ac 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.202 2006/05/30 14:01:57 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.203 2006/06/16 20:23:44 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -452,7 +452,8 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
  * DropTrigger - drop an individual trigger by name
  */
 void
-DropTrigger(Oid relid, const char *trigname, DropBehavior behavior)
+DropTrigger(Oid relid, const char *trigname, DropBehavior behavior,
+			bool missing_ok)
 {
 	Relation	tgrel;
 	ScanKeyData skey[2];
@@ -481,10 +482,21 @@ DropTrigger(Oid relid, const char *trigname, DropBehavior behavior)
 	tup = systable_getnext(tgscan);
 
 	if (!HeapTupleIsValid(tup))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("trigger \"%s\" for table \"%s\" does not exist",
-						trigname, get_rel_name(relid))));
+	{
+		if (! missing_ok)
+			ereport(ERROR,
+					(errcode(ERRCODE_UNDEFINED_OBJECT),
+					 errmsg("trigger \"%s\" for table \"%s\" does not exist",
+							trigname, get_rel_name(relid))));
+		else
+			ereport(NOTICE,
+					(errmsg("trigger \"%s\" for table \"%s\" does not exist ...skipping",
+							trigname, get_rel_name(relid))));
+		/* cleanup */
+		systable_endscan(tgscan);
+		heap_close(tgrel, AccessShareLock);
+		return;
+	}
 
 	if (!pg_class_ownercheck(relid, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 6bf342ab92c00c5b9de0569a9d0e5e051958843e..e213df5b2175460f5d8cb7df157ea0f9d1b1f780 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.335 2006/04/30 18:30:38 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.336 2006/06/16 20:23:44 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2075,6 +2075,7 @@ _copyRemoveFuncStmt(RemoveFuncStmt *from)
 	COPY_NODE_FIELD(name);
 	COPY_NODE_FIELD(args);
 	COPY_SCALAR_FIELD(behavior);
+	COPY_SCALAR_FIELD(missing_ok);
 
 	return newnode;
 }
@@ -2087,6 +2088,7 @@ _copyRemoveOpClassStmt(RemoveOpClassStmt *from)
 	COPY_NODE_FIELD(opclassname);
 	COPY_STRING_FIELD(amname);
 	COPY_SCALAR_FIELD(behavior);
+	COPY_SCALAR_FIELD(missing_ok);
 
 	return newnode;
 }
@@ -2414,6 +2416,7 @@ _copyDropTableSpaceStmt(DropTableSpaceStmt *from)
 	DropTableSpaceStmt *newnode = makeNode(DropTableSpaceStmt);
 
 	COPY_STRING_FIELD(tablespacename);
+	COPY_SCALAR_FIELD(missing_ok);
 
 	return newnode;
 }
@@ -2447,6 +2450,7 @@ _copyDropPropertyStmt(DropPropertyStmt *from)
 	COPY_STRING_FIELD(property);
 	COPY_SCALAR_FIELD(removeType);
 	COPY_SCALAR_FIELD(behavior);
+	COPY_SCALAR_FIELD(missing_ok);
 
 	return newnode;
 }
@@ -2471,6 +2475,7 @@ _copyDropPLangStmt(DropPLangStmt *from)
 
 	COPY_STRING_FIELD(plname);
 	COPY_SCALAR_FIELD(behavior);
+	COPY_SCALAR_FIELD(missing_ok);
 
 	return newnode;
 }
@@ -2606,6 +2611,7 @@ _copyDropCastStmt(DropCastStmt *from)
 	COPY_NODE_FIELD(sourcetype);
 	COPY_NODE_FIELD(targettype);
 	COPY_SCALAR_FIELD(behavior);
+	COPY_SCALAR_FIELD(missing_ok);
 
 	return newnode;
 }
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 7f7eb06fbcd8c37299293dd460f71cb6b1b4c68e..cc60fdd8dd6ca74410c32acf51375677f032abd0 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -18,7 +18,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.271 2006/04/30 18:30:38 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.272 2006/06/16 20:23:44 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -999,6 +999,7 @@ _equalRemoveFuncStmt(RemoveFuncStmt *a, RemoveFuncStmt *b)
 	COMPARE_NODE_FIELD(name);
 	COMPARE_NODE_FIELD(args);
 	COMPARE_SCALAR_FIELD(behavior);
+	COMPARE_SCALAR_FIELD(missing_ok);
 
 	return true;
 }
@@ -1009,6 +1010,7 @@ _equalRemoveOpClassStmt(RemoveOpClassStmt *a, RemoveOpClassStmt *b)
 	COMPARE_NODE_FIELD(opclassname);
 	COMPARE_STRING_FIELD(amname);
 	COMPARE_SCALAR_FIELD(behavior);
+	COMPARE_SCALAR_FIELD(missing_ok);
 
 	return true;
 }
@@ -1282,6 +1284,7 @@ static bool
 _equalDropTableSpaceStmt(DropTableSpaceStmt *a, DropTableSpaceStmt *b)
 {
 	COMPARE_STRING_FIELD(tablespacename);
+	COMPARE_SCALAR_FIELD(missing_ok);
 
 	return true;
 }
@@ -1312,6 +1315,7 @@ _equalDropPropertyStmt(DropPropertyStmt *a, DropPropertyStmt *b)
 	COMPARE_STRING_FIELD(property);
 	COMPARE_SCALAR_FIELD(removeType);
 	COMPARE_SCALAR_FIELD(behavior);
+	COMPARE_SCALAR_FIELD(missing_ok);
 
 	return true;
 }
@@ -1332,6 +1336,7 @@ _equalDropPLangStmt(DropPLangStmt *a, DropPLangStmt *b)
 {
 	COMPARE_STRING_FIELD(plname);
 	COMPARE_SCALAR_FIELD(behavior);
+	COMPARE_SCALAR_FIELD(missing_ok);
 
 	return true;
 }
@@ -1445,6 +1450,7 @@ _equalDropCastStmt(DropCastStmt *a, DropCastStmt *b)
 	COMPARE_NODE_FIELD(sourcetype);
 	COMPARE_NODE_FIELD(targettype);
 	COMPARE_SCALAR_FIELD(behavior);
+	COMPARE_SCALAR_FIELD(missing_ok);
 
 	return true;
 }
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index d84f4034abab41cba17a337959633ad17dca107a..f95a6b74cdf5d09f36b9bda4988cbd90eb9b9b39 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.545 2006/05/27 17:38:45 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.546 2006/06/16 20:23:44 adunstan Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -191,7 +191,7 @@ static void doNegateFloat(Value *v);
 %type <ival>	opt_lock lock_type cast_context
 %type <boolean>	opt_force opt_or_replace
 				opt_grant_grant_option opt_grant_admin_option
-				opt_nowait 
+				opt_nowait opt_if_exists
 
 %type <boolean>	like_including_defaults
 
@@ -2401,6 +2401,15 @@ DropPLangStmt:
 					DropPLangStmt *n = makeNode(DropPLangStmt);
 					n->plname = $4;
 					n->behavior = $5;
+					n->missing_ok = false;
+					$$ = (Node *)n;
+				}
+			| DROP opt_procedural LANGUAGE IF_P EXISTS ColId_or_Sconst opt_drop_behavior
+				{
+					DropPLangStmt *n = makeNode(DropPLangStmt);
+					n->plname = $6;
+					n->behavior = $7;
+					n->missing_ok = true;
 					$$ = (Node *)n;
 				}
 		;
@@ -2445,6 +2454,14 @@ DropTableSpaceStmt: DROP TABLESPACE name
 				{
 					DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt);
 					n->tablespacename = $3;
+					n->missing_ok = false;
+					$$ = (Node *) n;
+				}
+				|  DROP TABLESPACE IF_P EXISTS name
+                {
+					DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt);
+					n->tablespacename = $5;
+					n->missing_ok = true;
 					$$ = (Node *) n;
 				}
 		;
@@ -2630,6 +2647,17 @@ DropTrigStmt:
 					n->property = $3;
 					n->behavior = $6;
 					n->removeType = OBJECT_TRIGGER;
+					n->missing_ok = false;
+					$$ = (Node *) n;
+				}
+			| DROP TRIGGER IF_P EXISTS name ON qualified_name opt_drop_behavior
+				{
+					DropPropertyStmt *n = makeNode(DropPropertyStmt);
+					n->relation = $7;
+					n->property = $5;
+					n->behavior = $8;
+					n->removeType = OBJECT_TRIGGER;
+					n->missing_ok = true;
 					$$ = (Node *) n;
 				}
 		;
@@ -2903,6 +2931,16 @@ DropOpClassStmt:
 					n->opclassname = $4;
 					n->amname = $6;
 					n->behavior = $7;
+					n->missing_ok = false;
+					$$ = (Node *) n;
+				}
+			| DROP OPERATOR CLASS IF_P EXISTS any_name USING access_method opt_drop_behavior
+				{
+					RemoveOpClassStmt *n = makeNode(RemoveOpClassStmt);
+					n->opclassname = $6;
+					n->amname = $8;
+					n->behavior = $9;
+					n->missing_ok = true;
 					$$ = (Node *) n;
 				}
 		;
@@ -3912,6 +3950,17 @@ RemoveFuncStmt:
 					n->name = $3;
 					n->args = extractArgTypes($4);
 					n->behavior = $5;
+					n->missing_ok = false;
+					$$ = (Node *)n;
+				}
+			| DROP FUNCTION IF_P EXISTS func_name func_args opt_drop_behavior
+				{
+					RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
+					n->kind = OBJECT_FUNCTION;
+					n->name = $5;
+					n->args = extractArgTypes($6);
+					n->behavior = $7;
+					n->missing_ok = true;
 					$$ = (Node *)n;
 				}
 		;
@@ -3924,6 +3973,17 @@ RemoveAggrStmt:
 					n->name = $3;
 					n->args = $4;
 					n->behavior = $5;
+					n->missing_ok = false;
+					$$ = (Node *)n;
+				}
+			| DROP AGGREGATE IF_P EXISTS func_name aggr_args opt_drop_behavior
+				{
+					RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
+					n->kind = OBJECT_AGGREGATE;
+					n->name = $5;
+					n->args = $6;
+					n->behavior = $7;
+					n->missing_ok = true;
 					$$ = (Node *)n;
 				}
 		;
@@ -3936,6 +3996,17 @@ RemoveOperStmt:
 					n->name = $3;
 					n->args = $5;
 					n->behavior = $7;
+					n->missing_ok = false;
+					$$ = (Node *)n;
+				}
+			| DROP OPERATOR IF_P EXISTS any_operator '(' oper_argtypes ')' opt_drop_behavior
+				{
+					RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
+					n->kind = OBJECT_OPERATOR;
+					n->name = $5;
+					n->args = $7;
+					n->behavior = $9;
+					n->missing_ok = true;
 					$$ = (Node *)n;
 				}
 		;
@@ -3998,16 +4069,21 @@ cast_context:  AS IMPLICIT_P					{ $$ = COERCION_IMPLICIT; }
 		;
 
 
-DropCastStmt: DROP CAST '(' Typename AS Typename ')' opt_drop_behavior
+DropCastStmt: DROP CAST opt_if_exists '(' Typename AS Typename ')' opt_drop_behavior
 				{
 					DropCastStmt *n = makeNode(DropCastStmt);
-					n->sourcetype = $4;
-					n->targettype = $6;
-					n->behavior = $8;
+					n->sourcetype = $5;
+					n->targettype = $7;
+					n->behavior = $9;
+					n->missing_ok =
 					$$ = (Node *)n;
 				}
 		;
 
+opt_if_exists: IF_P EXISTS { $$ = true; }
+               | /* empty */ { $$ = false; }
+        ;
+
 
 
 /*****************************************************************************
@@ -4432,6 +4508,17 @@ DropRuleStmt:
 					n->property = $3;
 					n->behavior = $6;
 					n->removeType = OBJECT_RULE;
+					n->missing_ok = false;
+					$$ = (Node *) n;
+				}
+			| DROP RULE IF_P EXISTS name ON qualified_name opt_drop_behavior
+				{
+					DropPropertyStmt *n = makeNode(DropPropertyStmt);
+					n->relation = $7;
+					n->property = $5;
+					n->behavior = $8;
+					n->removeType = OBJECT_RULE;
+					n->missing_ok = true;
 					$$ = (Node *) n;
 				}
 		;
diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c
index 97a4a3247da6e38b4b66ecdbb6a21fa27aaa7ef9..b0acc01f8273289936f33c4afc99cf1c1247a1f1 100644
--- a/src/backend/rewrite/rewriteRemove.c
+++ b/src/backend/rewrite/rewriteRemove.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/rewrite/rewriteRemove.c,v 1.64 2006/03/05 15:58:36 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/rewrite/rewriteRemove.c,v 1.65 2006/06/16 20:23:44 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,7 +34,8 @@
  * Delete a rule given its name.
  */
 void
-RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior)
+RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior,
+	              bool missing_ok)
 {
 	HeapTuple	tuple;
 	Oid			eventRelationOid;
@@ -53,10 +54,18 @@ RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior)
 	 * complain if no rule with such name exists
 	 */
 	if (!HeapTupleIsValid(tuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("rule \"%s\" for relation \"%s\" does not exist",
-						ruleName, get_rel_name(owningRel))));
+	{
+		if (! missing_ok)
+			ereport(ERROR,
+					(errcode(ERRCODE_UNDEFINED_OBJECT),
+					 errmsg("rule \"%s\" for relation \"%s\" does not exist",
+							ruleName, get_rel_name(owningRel))));
+		else
+			ereport(NOTICE,
+					(errmsg("rule \"%s\" for relation \"%s\" does not exist ... skipping",
+							ruleName, get_rel_name(owningRel))));
+		return;
+	}
 
 	/*
 	 * Verify user has appropriate permissions.
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 5729b58450a651e4ce7214d2504f831a55b24ad2..749b96cb45cf47e3490589b7ee68a9dc6f9b51ea 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.257 2006/04/30 18:30:40 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.258 2006/06/16 20:23:44 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -986,12 +986,12 @@ ProcessUtility(Node *parsetree,
 					case OBJECT_RULE:
 						/* RemoveRewriteRule checks permissions */
 						RemoveRewriteRule(relId, stmt->property,
-										  stmt->behavior);
+										  stmt->behavior, stmt->missing_ok);
 						break;
 					case OBJECT_TRIGGER:
 						/* DropTrigger checks permissions */
 						DropTrigger(relId, stmt->property,
-									stmt->behavior);
+									stmt->behavior, stmt->missing_ok);
 						break;
 					default:
 						elog(ERROR, "unrecognized object type: %d",
diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h
index 7f83f8e4bbb4a7b5f2ba5181447ca15882a3998f..0cb4df7c4fa2d29c01a82eaf59a63c83ddbf0d5c 100644
--- a/src/include/commands/trigger.h
+++ b/src/include/commands/trigger.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/trigger.h,v 1.57 2006/03/05 15:58:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/commands/trigger.h,v 1.58 2006/06/16 20:23:45 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -108,7 +108,7 @@ typedef struct TriggerData
 extern Oid	CreateTrigger(CreateTrigStmt *stmt, bool forConstraint);
 
 extern void DropTrigger(Oid relid, const char *trigname,
-			DropBehavior behavior);
+			DropBehavior behavior, bool missing_ok);
 extern void RemoveTriggerById(Oid trigOid);
 
 extern void renametrig(Oid relid, const char *oldname, const char *newname);
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 896b426370dbf1dd7f06c4ad4b33dabbfcbe9562..56d41a2fd8d8f2ae79de19b5ac9010e975f81065 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.310 2006/04/30 18:30:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.311 2006/06/16 20:23:45 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1131,6 +1131,7 @@ typedef struct DropTableSpaceStmt
 {
 	NodeTag		type;
 	char	   *tablespacename;
+	bool		missing_ok;		/* skip error if a missing? */
 } DropTableSpaceStmt;
 
 /* ----------------------
@@ -1175,6 +1176,7 @@ typedef struct DropPLangStmt
 	NodeTag		type;
 	char	   *plname;			/* PL name */
 	DropBehavior behavior;		/* RESTRICT or CASCADE behavior */
+	bool		missing_ok;		/* skip error if missing? */
 } DropPLangStmt;
 
 /* ----------------------
@@ -1329,6 +1331,7 @@ typedef struct DropPropertyStmt
 	char	   *property;		/* name of rule, trigger, etc */
 	ObjectType	removeType;		/* OBJECT_RULE or OBJECT_TRIGGER */
 	DropBehavior behavior;		/* RESTRICT or CASCADE behavior */
+	bool		missing_ok;		/* skip error if a missing? */
 } DropPropertyStmt;
 
 /* ----------------------
@@ -1477,6 +1480,7 @@ typedef struct RemoveFuncStmt
 	List	   *name;			/* qualified name of object to drop */
 	List	   *args;			/* types of the arguments */
 	DropBehavior behavior;		/* RESTRICT or CASCADE behavior */
+	bool		missing_ok;		/* skip error if a missing? */
 } RemoveFuncStmt;
 
 /* ----------------------
@@ -1489,6 +1493,7 @@ typedef struct RemoveOpClassStmt
 	List	   *opclassname;	/* qualified name (list of Value strings) */
 	char	   *amname;			/* name of index AM opclass is for */
 	DropBehavior behavior;		/* RESTRICT or CASCADE behavior */
+	bool		missing_ok;		/* skip error if a missing? */
 } RemoveOpClassStmt;
 
 /* ----------------------
@@ -1846,6 +1851,7 @@ typedef struct DropCastStmt
 	TypeName   *sourcetype;
 	TypeName   *targettype;
 	DropBehavior behavior;
+	bool		missing_ok;		/* skip error if a missing? */
 } DropCastStmt;
 
 
diff --git a/src/include/rewrite/rewriteRemove.h b/src/include/rewrite/rewriteRemove.h
index d08501cfbe4c37575ea9d77a3724622cb4d4566c..76b003985d16cbe43ce8722b5804809b51387791 100644
--- a/src/include/rewrite/rewriteRemove.h
+++ b/src/include/rewrite/rewriteRemove.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/rewrite/rewriteRemove.h,v 1.21 2006/03/05 15:58:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/rewrite/rewriteRemove.h,v 1.22 2006/06/16 20:23:45 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,7 +18,7 @@
 
 
 extern void RemoveRewriteRule(Oid owningRel, const char *ruleName,
-				  DropBehavior behavior);
+				  DropBehavior behavior, bool missing_ok);
 extern void RemoveRewriteRuleById(Oid ruleOid);
 
 #endif   /* REWRITEREMOVE_H */