pgsql-v9.2-drop-reworks-3.v7.patch

application/octet-stream

Filename: pgsql-v9.2-drop-reworks-3.v7.patch
Type: application/octet-stream
Part: 0
Message: Re: [v9.2] DROP statement reworks

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
Series: patch v9
File+
src/backend/commands/aggregatecmds.c 2 51
src/backend/commands/dropcmds.c 96 10
src/backend/commands/foreigncmds.c 0 83
src/backend/commands/functioncmds.c 0 111
src/backend/commands/opclasscmds.c 0 99
src/backend/commands/operatorcmds.c 0 50
src/backend/commands/proclang.c 0 43
src/backend/commands/trigger.c 0 36
src/backend/nodes/copyfuncs.c 1 127
src/backend/nodes/equalfuncs.c 1 111
src/backend/parser/gram.y 92 74
src/backend/rewrite/rewriteRemove.c 0 65
src/backend/tcop/utility.c 33 160
src/include/commands/defrem.h 0 8
src/include/commands/proclang.h 0 1
src/include/commands/trigger.h 0 2
src/include/nodes/nodes.h 0 8
src/include/nodes/parsenodes.h 4 99
src/include/rewrite/rewriteRemove.h 0 3
src/test/regress/expected/drop_if_exists.out 1 1
 src/backend/commands/aggregatecmds.c         |   53 +-------
 src/backend/commands/dropcmds.c              |  106 +++++++++++++--
 src/backend/commands/foreigncmds.c           |   83 -----------
 src/backend/commands/functioncmds.c          |  111 ---------------
 src/backend/commands/opclasscmds.c           |   99 -------------
 src/backend/commands/operatorcmds.c          |   50 -------
 src/backend/commands/proclang.c              |   43 ------
 src/backend/commands/trigger.c               |   36 -----
 src/backend/nodes/copyfuncs.c                |  128 +-----------------
 src/backend/nodes/equalfuncs.c               |  112 +---------------
 src/backend/parser/gram.y                    |  166 ++++++++++++----------
 src/backend/rewrite/rewriteRemove.c          |   65 ---------
 src/backend/tcop/utility.c                   |  193 +++++---------------------
 src/include/commands/defrem.h                |    8 -
 src/include/commands/proclang.h              |    1 -
 src/include/commands/trigger.h               |    2 -
 src/include/nodes/nodes.h                    |    8 -
 src/include/nodes/parsenodes.h               |  103 +-------------
 src/include/rewrite/rewriteRemove.h          |    3 -
 src/test/regress/expected/drop_if_exists.out |    2 +-
 20 files changed, 230 insertions(+), 1142 deletions(-)

diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c
index a2122c1..085a205 100644
--- a/src/backend/commands/aggregatecmds.c
+++ b/src/backend/commands/aggregatecmds.c
@@ -208,59 +208,10 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters)
 
 
 /*
- * RemoveAggregate
- *		Deletes an aggregate.
+ * RenameAggregate
+ *		Rename an aggregate.
  */
 void
-RemoveAggregate(RemoveFuncStmt *stmt)
-{
-	List	   *aggName = stmt->name;
-	List	   *aggArgs = stmt->args;
-	Oid			procOid;
-	HeapTuple	tup;
-	ObjectAddress object;
-
-	/* Look up function and make sure it's an aggregate */
-	procOid = LookupAggNameTypeNames(aggName, aggArgs, stmt->missing_ok);
-
-	if (!OidIsValid(procOid))
-	{
-		/* we only get here if stmt->missing_ok is true */
-		ereport(NOTICE,
-				(errmsg("aggregate %s(%s) does not exist, skipping",
-						NameListToString(aggName),
-						TypeNameListToString(aggArgs))));
-		return;
-	}
-
-	/*
-	 * Find the function tuple, do permissions and validity checks
-	 */
-	tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(procOid));
-	if (!HeapTupleIsValid(tup)) /* should not happen */
-		elog(ERROR, "cache lookup failed for function %u", procOid);
-
-	/* Permission check: must own agg or its namespace */
-	if (!pg_proc_ownercheck(procOid, GetUserId()) &&
-	  !pg_namespace_ownercheck(((Form_pg_proc) GETSTRUCT(tup))->pronamespace,
-							   GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
-					   NameListToString(aggName));
-
-	ReleaseSysCache(tup);
-
-	/*
-	 * Do the deletion
-	 */
-	object.classId = ProcedureRelationId;
-	object.objectId = procOid;
-	object.objectSubId = 0;
-
-	performDeletion(&object, stmt->behavior);
-}
-
-
-void
 RenameAggregate(List *name, List *args, const char *newname)
 {
 	Oid			procOid;
diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c
index 8297730..ef70168 100644
--- a/src/backend/commands/dropcmds.c
+++ b/src/backend/commands/dropcmds.c
@@ -25,8 +25,10 @@
 #include "nodes/makefuncs.h"
 #include "parser/parse_type.h"
 #include "utils/acl.h"
+#include "utils/builtins.h"
 
-static void does_not_exist_skipping(ObjectType objtype, List *objname);
+static void does_not_exist_skipping(ObjectType objtype,
+									List *objname, List *objargs);
 
 /*
  * Drop one or more objects.
@@ -44,6 +46,7 @@ RemoveObjects(DropStmt *stmt)
 {
 	ObjectAddresses *objects;
 	ListCell   *cell1;
+	ListCell   *cell2 = NULL;
 
 	objects = new_object_addresses();
 
@@ -51,12 +54,19 @@ RemoveObjects(DropStmt *stmt)
 	{
 		ObjectAddress	address;
 		List	   *objname = lfirst(cell1);
+		List	   *objargs = NIL;
 		Relation	relation = NULL;
 		Oid			namespaceId;
 
+		if (stmt->arguments)
+		{
+			cell2 = (!cell2 ? list_head(stmt->arguments) : lnext(cell2));
+			objargs = lfirst(cell2);
+		}
+
 		/* Get an ObjectAddress for the object. */
 		address = get_object_address(stmt->removeType,
-									 objname, NIL,
+									 objname, objargs,
 									 &relation,
 									 AccessExclusiveLock,
 									 stmt->missing_ok);
@@ -64,16 +74,33 @@ RemoveObjects(DropStmt *stmt)
 		/* Issue NOTICE if supplied object was not found. */
 		if (!OidIsValid(address.objectId))
 		{
-			does_not_exist_skipping(stmt->removeType, objname);
+			does_not_exist_skipping(stmt->removeType, objname, objargs);
 			continue;
 		}
 
 		/* Check permissions. */
-		namespaceId = get_object_namespace(&address);
-		if (!OidIsValid(namespaceId) ||
-			!pg_namespace_ownercheck(namespaceId, GetUserId()))
-			check_object_ownership(GetUserId(), stmt->removeType, address,
-								   objname, NIL, relation);
+		if (stmt->removeType == OBJECT_FDW)
+		{
+			/*
+			 * Foreign Data Wrapper is an exception of access control on
+			 * deletion; it requires superuser privilege to drop it,
+			 * instead of ownership on the target object.
+			 */
+			if (!superuser())
+				ereport(ERROR,
+						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+				errmsg("permission denied to drop foreign-data wrapper \"%s\"",
+								NameListToString(objname)),
+				errhint("Must be superuser to drop a foreign-data wrapper.")));
+		}
+		else
+		{
+			namespaceId = get_object_namespace(&address);
+			if (!OidIsValid(namespaceId) ||
+				!pg_namespace_ownercheck(namespaceId, GetUserId()))
+				check_object_ownership(GetUserId(), stmt->removeType, address,
+									   objname, objargs, relation);
+		}
 
 		/* Release any relcache reference count, but keep lock until commit. */
 		if (relation)
@@ -94,10 +121,11 @@ RemoveObjects(DropStmt *stmt)
  * get_object_address() will throw an ERROR.
  */
 static void
-does_not_exist_skipping(ObjectType objtype, List *objname)
+does_not_exist_skipping(ObjectType objtype, List *objname, List *objargs)
 {
 	const char *msg = NULL;
 	char	   *name = NULL;
+	char	   *args = NULL;
 
 	switch (objtype)
 	{
@@ -138,10 +166,68 @@ does_not_exist_skipping(ObjectType objtype, List *objname)
 			msg = gettext_noop("extension \"%s\" does not exist, skipping");
 			name = NameListToString(objname);
 			break;
+		case OBJECT_FUNCTION:
+			msg = gettext_noop("function %s(%s) does not exist, skipping");
+			name = NameListToString(objname);
+			args = TypeNameListToString(objargs);
+			break;
+		case OBJECT_AGGREGATE:
+			msg = gettext_noop("aggregate %s(%s) does not exist, skipping");
+			name = NameListToString(objname);
+			args = TypeNameListToString(objargs);
+			break;
+		case OBJECT_OPERATOR:
+			msg = gettext_noop("operator %s does not exist, skipping");
+			name = NameListToString(objname);
+			break;
+		case OBJECT_LANGUAGE:
+			msg = gettext_noop("language \"%s\" does not exist, skipping");
+			name = NameListToString(objname);
+			break;
+		case OBJECT_CAST:
+			msg = gettext_noop("cast from type %s to type %s does not exist, skipping");
+			name = format_type_be(typenameTypeId(NULL,
+								  (TypeName *) linitial(objname)));
+			args = format_type_be(typenameTypeId(NULL,
+								  (TypeName *) linitial(objargs)));
+			break;
+		case OBJECT_TRIGGER:
+			msg = gettext_noop("trigger \"%s\" for table \"%s\" does not exist, skipping");
+			name = strVal(llast(objname));
+			args = NameListToString(list_truncate(objname,
+												  list_length(objname) - 1));
+			break;
+		case OBJECT_RULE:
+			msg = gettext_noop("rule \"%s\" for relation \"%s\" does not exist, skipping");
+			name = strVal(llast(objname));
+			args = NameListToString(list_truncate(objname,
+												  list_length(objname) - 1));
+			break;
+		case OBJECT_FDW:
+			msg = gettext_noop("foreign-data wrapper \"%s\" does not exist, skipping");
+			name = NameListToString(objname);
+			break;
+		case OBJECT_FOREIGN_SERVER:
+			msg = gettext_noop("server \"%s\" does not exist, skipping");
+			name = NameListToString(objname);
+			break;
+		case OBJECT_OPCLASS:
+			msg = gettext_noop("operator class \"%s\" does not exist for access method \"%s\", skipping");
+			name = NameListToString(objname);
+			args = strVal(linitial(objargs));
+			break;
+		case OBJECT_OPFAMILY:
+			msg= gettext_noop("operator family \"%s\" does not exist for access method \"%s\", skipping");
+		    name = NameListToString(objname);
+			args = strVal(linitial(objargs));
+			break;
 		default:
 			elog(ERROR, "unexpected object type (%d)", (int)objtype);
 			break;
 	}
 
-	ereport(NOTICE, (errmsg(msg, name)));
+	if (!args)
+		ereport(NOTICE, (errmsg(msg, name)));
+	else
+		ereport(NOTICE, (errmsg(msg, name, args)));
 }
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index d9c27d1..b30ff40 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -686,50 +686,6 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt)
 
 
 /*
- * Drop foreign-data wrapper
- */
-void
-RemoveForeignDataWrapper(DropFdwStmt *stmt)
-{
-	Oid			fdwId;
-	ObjectAddress object;
-
-	fdwId = get_foreign_data_wrapper_oid(stmt->fdwname, true);
-
-	if (!superuser())
-		ereport(ERROR,
-				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-			  errmsg("permission denied to drop foreign-data wrapper \"%s\"",
-					 stmt->fdwname),
-			  errhint("Must be superuser to drop a foreign-data wrapper.")));
-
-	if (!OidIsValid(fdwId))
-	{
-		if (!stmt->missing_ok)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("foreign-data wrapper \"%s\" does not exist",
-							stmt->fdwname)));
-
-		/* IF EXISTS specified, just note it */
-		ereport(NOTICE,
-			  (errmsg("foreign-data wrapper \"%s\" does not exist, skipping",
-					  stmt->fdwname)));
-		return;
-	}
-
-	/*
-	 * Do the deletion
-	 */
-	object.classId = ForeignDataWrapperRelationId;
-	object.objectId = fdwId;
-	object.objectSubId = 0;
-
-	performDeletion(&object, stmt->behavior);
-}
-
-
-/*
  * Drop foreign-data wrapper by OID
  */
 void
@@ -958,45 +914,6 @@ AlterForeignServer(AlterForeignServerStmt *stmt)
 
 
 /*
- * Drop foreign server
- */
-void
-RemoveForeignServer(DropForeignServerStmt *stmt)
-{
-	Oid			srvId;
-	ObjectAddress object;
-
-	srvId = get_foreign_server_oid(stmt->servername, true);
-
-	if (!OidIsValid(srvId))
-	{
-		/* Server not found, complain or notice */
-		if (!stmt->missing_ok)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-				  errmsg("server \"%s\" does not exist", stmt->servername)));
-
-		/* IF EXISTS specified, just note it */
-		ereport(NOTICE,
-				(errmsg("server \"%s\" does not exist, skipping",
-						stmt->servername)));
-		return;
-	}
-
-	/* Only allow DROP if the server is owned by the user. */
-	if (!pg_foreign_server_ownercheck(srvId, GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER,
-					   stmt->servername);
-
-	object.classId = ForeignServerRelationId;
-	object.objectId = srvId;
-	object.objectSubId = 0;
-
-	performDeletion(&object, stmt->behavior);
-}
-
-
-/*
  * Drop foreign server by OID
  */
 void
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 92abd44..09a975b 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -965,72 +965,6 @@ CreateFunction(CreateFunctionStmt *stmt, const char *queryString)
 
 
 /*
- * RemoveFunction
- *		Deletes a function.
- */
-void
-RemoveFunction(RemoveFuncStmt *stmt)
-{
-	List	   *functionName = stmt->name;
-	List	   *argTypes = stmt->args;	/* list of TypeName nodes */
-	Oid			funcOid;
-	HeapTuple	tup;
-	ObjectAddress object;
-
-	/*
-	 * Find the function, do permissions and validity checks
-	 */
-	funcOid = LookupFuncNameTypeNames(functionName, argTypes, stmt->missing_ok);
-	if (!OidIsValid(funcOid))
-	{
-		/* can only get here if stmt->missing_ok */
-		ereport(NOTICE,
-				(errmsg("function %s(%s) does not exist, skipping",
-						NameListToString(functionName),
-						TypeNameListToString(argTypes))));
-		return;
-	}
-
-	tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcOid));
-	if (!HeapTupleIsValid(tup)) /* should not happen */
-		elog(ERROR, "cache lookup failed for function %u", funcOid);
-
-	/* Permission check: must own func or its namespace */
-	if (!pg_proc_ownercheck(funcOid, GetUserId()) &&
-	  !pg_namespace_ownercheck(((Form_pg_proc) GETSTRUCT(tup))->pronamespace,
-							   GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
-					   NameListToString(functionName));
-
-	if (((Form_pg_proc) GETSTRUCT(tup))->proisagg)
-		ereport(ERROR,
-				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
-				 errmsg("\"%s\" is an aggregate function",
-						NameListToString(functionName)),
-				 errhint("Use DROP AGGREGATE to drop aggregate functions.")));
-
-	if (((Form_pg_proc) GETSTRUCT(tup))->prolang == INTERNALlanguageId)
-	{
-		/* "Helpful" NOTICE when removing a builtin function ... */
-		ereport(NOTICE,
-				(errcode(ERRCODE_WARNING),
-				 errmsg("removing built-in function \"%s\"",
-						NameListToString(functionName))));
-	}
-
-	ReleaseSysCache(tup);
-
-	/*
-	 * Do the deletion
-	 */
-	object.classId = ProcedureRelationId;
-	object.objectId = funcOid;
-	object.objectSubId = 0;
-
-	performDeletion(&object, stmt->behavior);
-}
-
-/*
  * Guts of function deletion.
  *
  * Note: this is also used for aggregate deletion, since the OIDs of
@@ -1776,51 +1710,6 @@ CreateCast(CreateCastStmt *stmt)
 	heap_close(relation, RowExclusiveLock);
 }
 
-
-
-/*
- * DROP CAST
- */
-void
-DropCast(DropCastStmt *stmt)
-{
-	Oid			sourcetypeid;
-	Oid			targettypeid;
-	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);
-
-	object.classId = CastRelationId;
-	object.objectId = get_cast_oid(sourcetypeid, targettypeid,
-								   stmt->missing_ok);
-	object.objectSubId = 0;
-
-	if (!OidIsValid(object.objectId))
-	{
-		ereport(NOTICE,
-			 (errmsg("cast from type %s to type %s does not exist, skipping",
-					 format_type_be(sourcetypeid),
-					 format_type_be(targettypeid))));
-		return;
-	}
-
-	/* Permission check */
-	if (!pg_type_ownercheck(sourcetypeid, GetUserId())
-		&& !pg_type_ownercheck(targettypeid, GetUserId()))
-		ereport(ERROR,
-				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-				 errmsg("must be owner of type %s or type %s",
-						format_type_be(sourcetypeid),
-						format_type_be(targettypeid))));
-
-	/*
-	 * Do the deletion
-	 */
-	performDeletion(&object, stmt->behavior);
-}
-
 /*
  * get_cast_oid - given two type OIDs, look up a cast OID
  *
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 5dde78a..0ef3584 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -1543,105 +1543,6 @@ dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid,
 	}
 }
 
-
-/*
- * RemoveOpClass
- *		Deletes an opclass.
- */
-void
-RemoveOpClass(RemoveOpClassStmt *stmt)
-{
-	Oid			amID,
-				opcID;
-	HeapTuple	tuple;
-	ObjectAddress object;
-
-	/* Get the access method's OID. */
-	amID = get_am_oid(stmt->amname, false);
-
-	/* Look up the opclass. */
-	tuple = OpClassCacheLookup(amID, stmt->opclassname, stmt->missing_ok);
-	if (!HeapTupleIsValid(tuple))
-	{
-		ereport(NOTICE,
-				(errmsg("operator class \"%s\" does not exist for access method \"%s\", skipping",
-						NameListToString(stmt->opclassname), stmt->amname)));
-		return;
-	}
-
-	opcID = HeapTupleGetOid(tuple);
-
-	/* Permission check: must own opclass or its namespace */
-	if (!pg_opclass_ownercheck(opcID, GetUserId()) &&
-		!pg_namespace_ownercheck(((Form_pg_opclass) GETSTRUCT(tuple))->opcnamespace,
-								 GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS,
-					   NameListToString(stmt->opclassname));
-
-	ReleaseSysCache(tuple);
-
-	/*
-	 * Do the deletion
-	 */
-	object.classId = OperatorClassRelationId;
-	object.objectId = opcID;
-	object.objectSubId = 0;
-
-	performDeletion(&object, stmt->behavior);
-}
-
-/*
- * RemoveOpFamily
- *		Deletes an opfamily.
- */
-void
-RemoveOpFamily(RemoveOpFamilyStmt *stmt)
-{
-	Oid			amID,
-				opfID;
-	HeapTuple	tuple;
-	ObjectAddress object;
-
-	/*
-	 * Get the access method's OID.
-	 */
-	amID = get_am_oid(stmt->amname, false);
-
-	/*
-	 * Look up the opfamily.
-	 */
-	tuple = OpFamilyCacheLookup(amID, stmt->opfamilyname, stmt->missing_ok);
-	if (!HeapTupleIsValid(tuple))
-	{
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-						NameListToString(stmt->opfamilyname), stmt->amname)));
-		return;
-	}
-
-	opfID = HeapTupleGetOid(tuple);
-
-	/* Permission check: must own opfamily or its namespace */
-	if (!pg_opfamily_ownercheck(opfID, GetUserId()) &&
-		!pg_namespace_ownercheck(((Form_pg_opfamily) GETSTRUCT(tuple))->opfnamespace,
-								 GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY,
-					   NameListToString(stmt->opfamilyname));
-
-	ReleaseSysCache(tuple);
-
-	/*
-	 * Do the deletion
-	 */
-	object.classId = OperatorFamilyRelationId;
-	object.objectId = opfID;
-	object.objectSubId = 0;
-
-	performDeletion(&object, stmt->behavior);
-}
-
-
 /*
  * Deletion subroutines for use by dependency.c.
  */
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index c5c18ee..1e6c5ce 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -291,56 +291,6 @@ DefineOperator(List *names, List *parameters)
 
 
 /*
- * RemoveOperator
- *		Deletes an operator.
- */
-void
-RemoveOperator(RemoveFuncStmt *stmt)
-{
-	List	   *operatorName = stmt->name;
-	TypeName   *typeName1 = (TypeName *) linitial(stmt->args);
-	TypeName   *typeName2 = (TypeName *) lsecond(stmt->args);
-	Oid			operOid;
-	HeapTuple	tup;
-	ObjectAddress object;
-
-	Assert(list_length(stmt->args) == 2);
-	operOid = LookupOperNameTypeNames(NULL, operatorName,
-									  typeName1, typeName2,
-									  stmt->missing_ok, -1);
-
-	if (stmt->missing_ok && !OidIsValid(operOid))
-	{
-		ereport(NOTICE,
-				(errmsg("operator %s does not exist, skipping",
-						NameListToString(operatorName))));
-		return;
-	}
-
-	tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
-	if (!HeapTupleIsValid(tup)) /* should not happen */
-		elog(ERROR, "cache lookup failed for operator %u", operOid);
-
-	/* Permission check: must own operator or its namespace */
-	if (!pg_oper_ownercheck(operOid, GetUserId()) &&
-		!pg_namespace_ownercheck(((Form_pg_operator) GETSTRUCT(tup))->oprnamespace,
-								 GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPER,
-					   NameListToString(operatorName));
-
-	ReleaseSysCache(tup);
-
-	/*
-	 * Do the deletion
-	 */
-	object.classId = OperatorRelationId;
-	object.objectId = operOid;
-	object.objectSubId = 0;
-
-	performDeletion(&object, stmt->behavior);
-}
-
-/*
  * Guts of operator deletion.
  */
 void
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 98770c5..b7ed1a4 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -513,49 +513,6 @@ PLTemplateExists(const char *languageName)
 	return (find_language_template(languageName) != NULL);
 }
 
-
-/* ---------------------------------------------------------------------
- * DROP PROCEDURAL LANGUAGE
- * ---------------------------------------------------------------------
- */
-void
-DropProceduralLanguage(DropPLangStmt *stmt)
-{
-	char	   *languageName;
-	Oid			oid;
-	ObjectAddress object;
-
-	/*
-	 * Translate the language name, check that the language exists
-	 */
-	languageName = case_translate_language_name(stmt->plname);
-
-	oid = get_language_oid(languageName, stmt->missing_ok);
-	if (!OidIsValid(oid))
-	{
-		ereport(NOTICE,
-				(errmsg("language \"%s\" does not exist, skipping",
-						languageName)));
-		return;
-	}
-
-	/*
-	 * Check permission
-	 */
-	if (!pg_language_ownercheck(oid, GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
-					   languageName);
-
-	object.classId = LanguageRelationId;
-	object.objectId = oid;
-	object.objectSubId = 0;
-
-	/*
-	 * Do the deletion
-	 */
-	performDeletion(&object, stmt->behavior);
-}
-
 /*
  * Guts of language dropping.
  */
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 9fb9754..5589528 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -1026,42 +1026,6 @@ ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid)
 	}
 }
 
-
-/*
- * DropTrigger - drop an individual trigger by name
- */
-void
-DropTrigger(RangeVar *relation, const char *trigname, DropBehavior behavior,
-			bool missing_ok)
-{
-	Oid			relid;
-	ObjectAddress object;
-
-	/* lock level should match RemoveTriggerById */
-	relid = RangeVarGetRelid(relation, ShareRowExclusiveLock, false, false);
-
-	object.classId = TriggerRelationId;
-	object.objectId = get_trigger_oid(relid, trigname, missing_ok);
-	object.objectSubId = 0;
-
-	if (!OidIsValid(object.objectId))
-	{
-		ereport(NOTICE,
-		  (errmsg("trigger \"%s\" for table \"%s\" does not exist, skipping",
-				  trigname, get_rel_name(relid))));
-		return;
-	}
-
-	if (!pg_class_ownercheck(relid, GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
-					   get_rel_name(relid));
-
-	/*
-	 * Do the deletion
-	 */
-	performDeletion(&object, behavior);
-}
-
 /*
  * Guts of trigger deletion.
  */
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 24ac529..b6dfcfc 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2755,6 +2755,7 @@ _copyDropStmt(DropStmt *from)
 	DropStmt   *newnode = makeNode(DropStmt);
 
 	COPY_NODE_FIELD(objects);
+	COPY_NODE_FIELD(arguments);
 	COPY_SCALAR_FIELD(removeType);
 	COPY_SCALAR_FIELD(behavior);
 	COPY_SCALAR_FIELD(missing_ok);
@@ -2878,20 +2879,6 @@ _copyAlterFunctionStmt(AlterFunctionStmt *from)
 	return newnode;
 }
 
-static RemoveFuncStmt *
-_copyRemoveFuncStmt(RemoveFuncStmt *from)
-{
-	RemoveFuncStmt *newnode = makeNode(RemoveFuncStmt);
-
-	COPY_SCALAR_FIELD(kind);
-	COPY_NODE_FIELD(name);
-	COPY_NODE_FIELD(args);
-	COPY_SCALAR_FIELD(behavior);
-	COPY_SCALAR_FIELD(missing_ok);
-
-	return newnode;
-}
-
 static DoStmt *
 _copyDoStmt(DoStmt *from)
 {
@@ -2902,32 +2889,6 @@ _copyDoStmt(DoStmt *from)
 	return newnode;
 }
 
-static RemoveOpClassStmt *
-_copyRemoveOpClassStmt(RemoveOpClassStmt *from)
-{
-	RemoveOpClassStmt *newnode = makeNode(RemoveOpClassStmt);
-
-	COPY_NODE_FIELD(opclassname);
-	COPY_STRING_FIELD(amname);
-	COPY_SCALAR_FIELD(behavior);
-	COPY_SCALAR_FIELD(missing_ok);
-
-	return newnode;
-}
-
-static RemoveOpFamilyStmt *
-_copyRemoveOpFamilyStmt(RemoveOpFamilyStmt *from)
-{
-	RemoveOpFamilyStmt *newnode = makeNode(RemoveOpFamilyStmt);
-
-	COPY_NODE_FIELD(opfamilyname);
-	COPY_STRING_FIELD(amname);
-	COPY_SCALAR_FIELD(behavior);
-	COPY_SCALAR_FIELD(missing_ok);
-
-	return newnode;
-}
-
 static RenameStmt *
 _copyRenameStmt(RenameStmt *from)
 {
@@ -3380,18 +3341,6 @@ _copyAlterFdwStmt(AlterFdwStmt *from)
 	return newnode;
 }
 
-static DropFdwStmt *
-_copyDropFdwStmt(DropFdwStmt *from)
-{
-	DropFdwStmt *newnode = makeNode(DropFdwStmt);
-
-	COPY_STRING_FIELD(fdwname);
-	COPY_SCALAR_FIELD(missing_ok);
-	COPY_SCALAR_FIELD(behavior);
-
-	return newnode;
-}
-
 static CreateForeignServerStmt *
 _copyCreateForeignServerStmt(CreateForeignServerStmt *from)
 {
@@ -3419,18 +3368,6 @@ _copyAlterForeignServerStmt(AlterForeignServerStmt *from)
 	return newnode;
 }
 
-static DropForeignServerStmt *
-_copyDropForeignServerStmt(DropForeignServerStmt *from)
-{
-	DropForeignServerStmt *newnode = makeNode(DropForeignServerStmt);
-
-	COPY_STRING_FIELD(servername);
-	COPY_SCALAR_FIELD(missing_ok);
-	COPY_SCALAR_FIELD(behavior);
-
-	return newnode;
-}
-
 static CreateUserMappingStmt *
 _copyCreateUserMappingStmt(CreateUserMappingStmt *from)
 {
@@ -3502,20 +3439,6 @@ _copyCreateTrigStmt(CreateTrigStmt *from)
 	return newnode;
 }
 
-static DropPropertyStmt *
-_copyDropPropertyStmt(DropPropertyStmt *from)
-{
-	DropPropertyStmt *newnode = makeNode(DropPropertyStmt);
-
-	COPY_NODE_FIELD(relation);
-	COPY_STRING_FIELD(property);
-	COPY_SCALAR_FIELD(removeType);
-	COPY_SCALAR_FIELD(behavior);
-	COPY_SCALAR_FIELD(missing_ok);
-
-	return newnode;
-}
-
 static CreatePLangStmt *
 _copyCreatePLangStmt(CreatePLangStmt *from)
 {
@@ -3531,18 +3454,6 @@ _copyCreatePLangStmt(CreatePLangStmt *from)
 	return newnode;
 }
 
-static DropPLangStmt *
-_copyDropPLangStmt(DropPLangStmt *from)
-{
-	DropPLangStmt *newnode = makeNode(DropPLangStmt);
-
-	COPY_STRING_FIELD(plname);
-	COPY_SCALAR_FIELD(behavior);
-	COPY_SCALAR_FIELD(missing_ok);
-
-	return newnode;
-}
-
 static CreateRoleStmt *
 _copyCreateRoleStmt(CreateRoleStmt *from)
 {
@@ -3667,19 +3578,6 @@ _copyCreateCastStmt(CreateCastStmt *from)
 	return newnode;
 }
 
-static DropCastStmt *
-_copyDropCastStmt(DropCastStmt *from)
-{
-	DropCastStmt *newnode = makeNode(DropCastStmt);
-
-	COPY_NODE_FIELD(sourcetype);
-	COPY_NODE_FIELD(targettype);
-	COPY_SCALAR_FIELD(behavior);
-	COPY_SCALAR_FIELD(missing_ok);
-
-	return newnode;
-}
-
 static PrepareStmt *
 _copyPrepareStmt(PrepareStmt *from)
 {
@@ -4255,18 +4153,9 @@ copyObject(void *from)
 		case T_AlterFunctionStmt:
 			retval = _copyAlterFunctionStmt(from);
 			break;
-		case T_RemoveFuncStmt:
-			retval = _copyRemoveFuncStmt(from);
-			break;
 		case T_DoStmt:
 			retval = _copyDoStmt(from);
 			break;
-		case T_RemoveOpClassStmt:
-			retval = _copyRemoveOpClassStmt(from);
-			break;
-		case T_RemoveOpFamilyStmt:
-			retval = _copyRemoveOpFamilyStmt(from);
-			break;
 		case T_RenameStmt:
 			retval = _copyRenameStmt(from);
 			break;
@@ -4378,18 +4267,12 @@ copyObject(void *from)
 		case T_AlterFdwStmt:
 			retval = _copyAlterFdwStmt(from);
 			break;
-		case T_DropFdwStmt:
-			retval = _copyDropFdwStmt(from);
-			break;
 		case T_CreateForeignServerStmt:
 			retval = _copyCreateForeignServerStmt(from);
 			break;
 		case T_AlterForeignServerStmt:
 			retval = _copyAlterForeignServerStmt(from);
 			break;
-		case T_DropForeignServerStmt:
-			retval = _copyDropForeignServerStmt(from);
-			break;
 		case T_CreateUserMappingStmt:
 			retval = _copyCreateUserMappingStmt(from);
 			break;
@@ -4405,15 +4288,9 @@ copyObject(void *from)
 		case T_CreateTrigStmt:
 			retval = _copyCreateTrigStmt(from);
 			break;
-		case T_DropPropertyStmt:
-			retval = _copyDropPropertyStmt(from);
-			break;
 		case T_CreatePLangStmt:
 			retval = _copyCreatePLangStmt(from);
 			break;
-		case T_DropPLangStmt:
-			retval = _copyDropPLangStmt(from);
-			break;
 		case T_CreateRoleStmt:
 			retval = _copyCreateRoleStmt(from);
 			break;
@@ -4447,9 +4324,6 @@ copyObject(void *from)
 		case T_CreateCastStmt:
 			retval = _copyCreateCastStmt(from);
 			break;
-		case T_DropCastStmt:
-			retval = _copyDropCastStmt(from);
-			break;
 		case T_PrepareStmt:
 			retval = _copyPrepareStmt(from);
 			break;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 4052a9a..b25431a 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1182,6 +1182,7 @@ static bool
 _equalDropStmt(DropStmt *a, DropStmt *b)
 {
 	COMPARE_NODE_FIELD(objects);
+	COMPARE_NODE_FIELD(arguments);
 	COMPARE_SCALAR_FIELD(removeType);
 	COMPARE_SCALAR_FIELD(behavior);
 	COMPARE_SCALAR_FIELD(missing_ok);
@@ -1290,18 +1291,6 @@ _equalAlterFunctionStmt(AlterFunctionStmt *a, AlterFunctionStmt *b)
 }
 
 static bool
-_equalRemoveFuncStmt(RemoveFuncStmt *a, RemoveFuncStmt *b)
-{
-	COMPARE_SCALAR_FIELD(kind);
-	COMPARE_NODE_FIELD(name);
-	COMPARE_NODE_FIELD(args);
-	COMPARE_SCALAR_FIELD(behavior);
-	COMPARE_SCALAR_FIELD(missing_ok);
-
-	return true;
-}
-
-static bool
 _equalDoStmt(DoStmt *a, DoStmt *b)
 {
 	COMPARE_NODE_FIELD(args);
@@ -1310,28 +1299,6 @@ _equalDoStmt(DoStmt *a, DoStmt *b)
 }
 
 static bool
-_equalRemoveOpClassStmt(RemoveOpClassStmt *a, RemoveOpClassStmt *b)
-{
-	COMPARE_NODE_FIELD(opclassname);
-	COMPARE_STRING_FIELD(amname);
-	COMPARE_SCALAR_FIELD(behavior);
-	COMPARE_SCALAR_FIELD(missing_ok);
-
-	return true;
-}
-
-static bool
-_equalRemoveOpFamilyStmt(RemoveOpFamilyStmt *a, RemoveOpFamilyStmt *b)
-{
-	COMPARE_NODE_FIELD(opfamilyname);
-	COMPARE_STRING_FIELD(amname);
-	COMPARE_SCALAR_FIELD(behavior);
-	COMPARE_SCALAR_FIELD(missing_ok);
-
-	return true;
-}
-
-static bool
 _equalRenameStmt(RenameStmt *a, RenameStmt *b)
 {
 	COMPARE_SCALAR_FIELD(renameType);
@@ -1711,16 +1678,6 @@ _equalAlterFdwStmt(AlterFdwStmt *a, AlterFdwStmt *b)
 }
 
 static bool
-_equalDropFdwStmt(DropFdwStmt *a, DropFdwStmt *b)
-{
-	COMPARE_STRING_FIELD(fdwname);
-	COMPARE_SCALAR_FIELD(missing_ok);
-	COMPARE_SCALAR_FIELD(behavior);
-
-	return true;
-}
-
-static bool
 _equalCreateForeignServerStmt(CreateForeignServerStmt *a, CreateForeignServerStmt *b)
 {
 	COMPARE_STRING_FIELD(servername);
@@ -1744,16 +1701,6 @@ _equalAlterForeignServerStmt(AlterForeignServerStmt *a, AlterForeignServerStmt *
 }
 
 static bool
-_equalDropForeignServerStmt(DropForeignServerStmt *a, DropForeignServerStmt *b)
-{
-	COMPARE_STRING_FIELD(servername);
-	COMPARE_SCALAR_FIELD(missing_ok);
-	COMPARE_SCALAR_FIELD(behavior);
-
-	return true;
-}
-
-static bool
 _equalCreateUserMappingStmt(CreateUserMappingStmt *a, CreateUserMappingStmt *b)
 {
 	COMPARE_STRING_FIELD(username);
@@ -1816,18 +1763,6 @@ _equalCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b)
 }
 
 static bool
-_equalDropPropertyStmt(DropPropertyStmt *a, DropPropertyStmt *b)
-{
-	COMPARE_NODE_FIELD(relation);
-	COMPARE_STRING_FIELD(property);
-	COMPARE_SCALAR_FIELD(removeType);
-	COMPARE_SCALAR_FIELD(behavior);
-	COMPARE_SCALAR_FIELD(missing_ok);
-
-	return true;
-}
-
-static bool
 _equalCreatePLangStmt(CreatePLangStmt *a, CreatePLangStmt *b)
 {
 	COMPARE_SCALAR_FIELD(replace);
@@ -1841,16 +1776,6 @@ _equalCreatePLangStmt(CreatePLangStmt *a, CreatePLangStmt *b)
 }
 
 static bool
-_equalDropPLangStmt(DropPLangStmt *a, DropPLangStmt *b)
-{
-	COMPARE_STRING_FIELD(plname);
-	COMPARE_SCALAR_FIELD(behavior);
-	COMPARE_SCALAR_FIELD(missing_ok);
-
-	return true;
-}
-
-static bool
 _equalCreateRoleStmt(CreateRoleStmt *a, CreateRoleStmt *b)
 {
 	COMPARE_SCALAR_FIELD(stmt_type);
@@ -1955,17 +1880,6 @@ _equalCreateCastStmt(CreateCastStmt *a, CreateCastStmt *b)
 }
 
 static bool
-_equalDropCastStmt(DropCastStmt *a, DropCastStmt *b)
-{
-	COMPARE_NODE_FIELD(sourcetype);
-	COMPARE_NODE_FIELD(targettype);
-	COMPARE_SCALAR_FIELD(behavior);
-	COMPARE_SCALAR_FIELD(missing_ok);
-
-	return true;
-}
-
-static bool
 _equalPrepareStmt(PrepareStmt *a, PrepareStmt *b)
 {
 	COMPARE_STRING_FIELD(name);
@@ -2784,18 +2698,9 @@ equal(void *a, void *b)
 		case T_AlterFunctionStmt:
 			retval = _equalAlterFunctionStmt(a, b);
 			break;
-		case T_RemoveFuncStmt:
-			retval = _equalRemoveFuncStmt(a, b);
-			break;
 		case T_DoStmt:
 			retval = _equalDoStmt(a, b);
 			break;
-		case T_RemoveOpClassStmt:
-			retval = _equalRemoveOpClassStmt(a, b);
-			break;
-		case T_RemoveOpFamilyStmt:
-			retval = _equalRemoveOpFamilyStmt(a, b);
-			break;
 		case T_RenameStmt:
 			retval = _equalRenameStmt(a, b);
 			break;
@@ -2907,18 +2812,12 @@ equal(void *a, void *b)
 		case T_AlterFdwStmt:
 			retval = _equalAlterFdwStmt(a, b);
 			break;
-		case T_DropFdwStmt:
-			retval = _equalDropFdwStmt(a, b);
-			break;
 		case T_CreateForeignServerStmt:
 			retval = _equalCreateForeignServerStmt(a, b);
 			break;
 		case T_AlterForeignServerStmt:
 			retval = _equalAlterForeignServerStmt(a, b);
 			break;
-		case T_DropForeignServerStmt:
-			retval = _equalDropForeignServerStmt(a, b);
-			break;
 		case T_CreateUserMappingStmt:
 			retval = _equalCreateUserMappingStmt(a, b);
 			break;
@@ -2934,15 +2833,9 @@ equal(void *a, void *b)
 		case T_CreateTrigStmt:
 			retval = _equalCreateTrigStmt(a, b);
 			break;
-		case T_DropPropertyStmt:
-			retval = _equalDropPropertyStmt(a, b);
-			break;
 		case T_CreatePLangStmt:
 			retval = _equalCreatePLangStmt(a, b);
 			break;
-		case T_DropPLangStmt:
-			retval = _equalDropPLangStmt(a, b);
-			break;
 		case T_CreateRoleStmt:
 			retval = _equalCreateRoleStmt(a, b);
 			break;
@@ -2976,9 +2869,6 @@ equal(void *a, void *b)
 		case T_CreateCastStmt:
 			retval = _equalCreateCastStmt(a, b);
 			break;
-		case T_DropCastStmt:
-			retval = _equalDropCastStmt(a, b);
-			break;
 		case T_PrepareStmt:
 			retval = _equalPrepareStmt(a, b);
 			break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index e9f3896..3eb55ae 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -3246,16 +3246,19 @@ opt_validator:
 DropPLangStmt:
 			DROP opt_procedural LANGUAGE ColId_or_Sconst opt_drop_behavior
 				{
-					DropPLangStmt *n = makeNode(DropPLangStmt);
-					n->plname = $4;
+					DropStmt *n = makeNode(DropStmt);
+					n->removeType = OBJECT_LANGUAGE;
+					n->objects = list_make1(list_make1(makeString($4)));
+					n->arguments = NIL;
 					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;
+					DropStmt *n = makeNode(DropStmt);
+					n->removeType = OBJECT_LANGUAGE;
+					n->objects = list_make1(list_make1(makeString($6)));
 					n->behavior = $7;
 					n->missing_ok = true;
 					$$ = (Node *)n;
@@ -3647,16 +3650,20 @@ opt_fdw_options:
 
 DropFdwStmt: DROP FOREIGN DATA_P WRAPPER name opt_drop_behavior
 				{
-					DropFdwStmt *n = makeNode(DropFdwStmt);
-					n->fdwname = $5;
+					DropStmt *n = makeNode(DropStmt);
+					n->removeType = OBJECT_FDW;
+					n->objects = list_make1(list_make1(makeString($5)));
+					n->arguments = NIL;
 					n->missing_ok = false;
 					n->behavior = $6;
 					$$ = (Node *) n;
 				}
 				|  DROP FOREIGN DATA_P WRAPPER IF_P EXISTS name opt_drop_behavior
                 {
-					DropFdwStmt *n = makeNode(DropFdwStmt);
-					n->fdwname = $7;
+					DropStmt *n = makeNode(DropStmt);
+					n->removeType = OBJECT_FDW;
+					n->objects = list_make1(list_make1(makeString($7)));
+					n->arguments = NIL;
 					n->missing_ok = true;
 					n->behavior = $8;
 					$$ = (Node *) n;
@@ -3803,16 +3810,20 @@ opt_foreign_server_version:
 
 DropForeignServerStmt: DROP SERVER name opt_drop_behavior
 				{
-					DropForeignServerStmt *n = makeNode(DropForeignServerStmt);
-					n->servername = $3;
+					DropStmt *n = makeNode(DropStmt);
+					n->removeType = OBJECT_FOREIGN_SERVER;
+					n->objects = list_make1(list_make1(makeString($3)));
+					n->arguments = NIL;
 					n->missing_ok = false;
 					n->behavior = $4;
 					$$ = (Node *) n;
 				}
 				|  DROP SERVER IF_P EXISTS name opt_drop_behavior
                 {
-					DropForeignServerStmt *n = makeNode(DropForeignServerStmt);
-					n->servername = $5;
+					DropStmt *n = makeNode(DropStmt);
+					n->removeType = OBJECT_FOREIGN_SERVER;
+					n->objects = list_make1(list_make1(makeString($5)));
+					n->arguments = NIL;
 					n->missing_ok = true;
 					n->behavior = $6;
 					$$ = (Node *) n;
@@ -4184,23 +4195,23 @@ ConstraintAttributeElem:
 
 
 DropTrigStmt:
-			DROP TRIGGER name ON qualified_name opt_drop_behavior
+			DROP TRIGGER name ON any_name opt_drop_behavior
 				{
-					DropPropertyStmt *n = makeNode(DropPropertyStmt);
-					n->relation = $5;
-					n->property = $3;
-					n->behavior = $6;
+					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_TRIGGER;
+					n->objects = list_make1(lappend($5, makeString($3)));
+					n->arguments = NIL;
+					n->behavior = $6;
 					n->missing_ok = false;
 					$$ = (Node *) n;
 				}
-			| DROP TRIGGER IF_P EXISTS name ON qualified_name opt_drop_behavior
+			| DROP TRIGGER IF_P EXISTS name ON any_name opt_drop_behavior
 				{
-					DropPropertyStmt *n = makeNode(DropPropertyStmt);
-					n->relation = $7;
-					n->property = $5;
-					n->behavior = $8;
+					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_TRIGGER;
+					n->objects = list_make1(lappend($7, makeString($5)));
+					n->arguments = NIL;
+					n->behavior = $8;
 					n->missing_ok = true;
 					$$ = (Node *) n;
 				}
@@ -4238,9 +4249,9 @@ CreateAssertStmt:
 DropAssertStmt:
 			DROP ASSERTION name opt_drop_behavior
 				{
-					DropPropertyStmt *n = makeNode(DropPropertyStmt);
-					n->relation = NULL;
-					n->property = $3;
+					DropStmt *n = makeNode(DropStmt);
+					n->objects = NIL;
+					n->arguments = NIL;
 					n->behavior = $4;
 					n->removeType = OBJECT_TRIGGER; /* XXX */
 					ereport(ERROR,
@@ -4649,18 +4660,20 @@ opclass_drop:
 DropOpClassStmt:
 			DROP OPERATOR CLASS any_name USING access_method opt_drop_behavior
 				{
-					RemoveOpClassStmt *n = makeNode(RemoveOpClassStmt);
-					n->opclassname = $4;
-					n->amname = $6;
+					DropStmt *n = makeNode(DropStmt);
+					n->objects = list_make1($4);
+					n->arguments = list_make1(list_make1(makeString($6)));
+					n->removeType = OBJECT_OPCLASS;
 					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;
+					DropStmt *n = makeNode(DropStmt);
+					n->objects = list_make1($6);
+					n->arguments = list_make1(list_make1(makeString($8)));
+					n->removeType = OBJECT_OPCLASS;
 					n->behavior = $9;
 					n->missing_ok = true;
 					$$ = (Node *) n;
@@ -4670,18 +4683,20 @@ DropOpClassStmt:
 DropOpFamilyStmt:
 			DROP OPERATOR FAMILY any_name USING access_method opt_drop_behavior
 				{
-					RemoveOpFamilyStmt *n = makeNode(RemoveOpFamilyStmt);
-					n->opfamilyname = $4;
-					n->amname = $6;
+					DropStmt *n = makeNode(DropStmt);
+					n->objects = list_make1($4);
+					n->arguments = list_make1(list_make1(makeString($6)));
+					n->removeType = OBJECT_OPFAMILY;
 					n->behavior = $7;
 					n->missing_ok = false;
 					$$ = (Node *) n;
 				}
 			| DROP OPERATOR FAMILY IF_P EXISTS any_name USING access_method opt_drop_behavior
 				{
-					RemoveOpFamilyStmt *n = makeNode(RemoveOpFamilyStmt);
-					n->opfamilyname = $6;
-					n->amname = $8;
+					DropStmt *n = makeNode(DropStmt);
+					n->objects = list_make1($6);
+					n->arguments = list_make1(list_make1(makeString($8)));
+					n->removeType = OBJECT_OPFAMILY;
 					n->behavior = $9;
 					n->missing_ok = true;
 					$$ = (Node *) n;
@@ -4732,6 +4747,7 @@ DropStmt:	DROP drop_type IF_P EXISTS any_name_list opt_drop_behavior
 					n->removeType = $2;
 					n->missing_ok = TRUE;
 					n->objects = $5;
+					n->arguments = NIL;
 					n->behavior = $6;
 					$$ = (Node *)n;
 				}
@@ -4741,6 +4757,7 @@ DropStmt:	DROP drop_type IF_P EXISTS any_name_list opt_drop_behavior
 					n->removeType = $2;
 					n->missing_ok = FALSE;
 					n->objects = $3;
+					n->arguments = NIL;
 					n->behavior = $4;
 					$$ = (Node *)n;
 				}
@@ -6157,20 +6174,20 @@ opt_restrict:
 RemoveFuncStmt:
 			DROP FUNCTION func_name func_args opt_drop_behavior
 				{
-					RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
-					n->kind = OBJECT_FUNCTION;
-					n->name = $3;
-					n->args = extractArgTypes($4);
+					DropStmt *n = makeNode(DropStmt);
+					n->removeType = OBJECT_FUNCTION;
+					n->objects = list_make1($3);
+					n->arguments = list_make1(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);
+					DropStmt *n = makeNode(DropStmt);
+					n->removeType = OBJECT_FUNCTION;
+					n->objects = list_make1($5);
+					n->arguments = list_make1(extractArgTypes($6));
 					n->behavior = $7;
 					n->missing_ok = true;
 					$$ = (Node *)n;
@@ -6180,20 +6197,20 @@ RemoveFuncStmt:
 RemoveAggrStmt:
 			DROP AGGREGATE func_name aggr_args opt_drop_behavior
 				{
-					RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
-					n->kind = OBJECT_AGGREGATE;
-					n->name = $3;
-					n->args = $4;
+					DropStmt *n = makeNode(DropStmt);
+					n->removeType = OBJECT_AGGREGATE;
+					n->objects = list_make1($3);
+					n->arguments = list_make1($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;
+					DropStmt *n = makeNode(DropStmt);
+					n->removeType = OBJECT_AGGREGATE;
+					n->objects = list_make1($5);
+					n->arguments = list_make1($6);
 					n->behavior = $7;
 					n->missing_ok = true;
 					$$ = (Node *)n;
@@ -6203,20 +6220,20 @@ RemoveAggrStmt:
 RemoveOperStmt:
 			DROP OPERATOR any_operator oper_argtypes opt_drop_behavior
 				{
-					RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
-					n->kind = OBJECT_OPERATOR;
-					n->name = $3;
-					n->args = $4;
+					DropStmt *n = makeNode(DropStmt);
+					n->removeType = OBJECT_OPERATOR;
+					n->objects = list_make1($3);
+					n->arguments = list_make1($4);
 					n->behavior = $5;
 					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 = $6;
+					DropStmt *n = makeNode(DropStmt);
+					n->removeType = OBJECT_OPERATOR;
+					n->objects = list_make1($5);
+					n->arguments = list_make1($6);
 					n->behavior = $7;
 					n->missing_ok = true;
 					$$ = (Node *)n;
@@ -6329,9 +6346,10 @@ cast_context:  AS IMPLICIT_P					{ $$ = COERCION_IMPLICIT; }
 
 DropCastStmt: DROP CAST opt_if_exists '(' Typename AS Typename ')' opt_drop_behavior
 				{
-					DropCastStmt *n = makeNode(DropCastStmt);
-					n->sourcetype = $5;
-					n->targettype = $7;
+					DropStmt *n = makeNode(DropStmt);
+					n->removeType = OBJECT_CAST;
+					n->objects = list_make1(list_make1($5));
+					n->arguments = list_make1(list_make1($7));
 					n->behavior = $9;
 					n->missing_ok = $3;
 					$$ = (Node *)n;
@@ -7047,23 +7065,23 @@ opt_instead:
 
 
 DropRuleStmt:
-			DROP RULE name ON qualified_name opt_drop_behavior
+			DROP RULE name ON any_name opt_drop_behavior
 				{
-					DropPropertyStmt *n = makeNode(DropPropertyStmt);
-					n->relation = $5;
-					n->property = $3;
-					n->behavior = $6;
+					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_RULE;
+					n->objects = list_make1(lappend($5, makeString($3)));
+					n->arguments = NIL;
+					n->behavior = $6;
 					n->missing_ok = false;
 					$$ = (Node *) n;
 				}
-			| DROP RULE IF_P EXISTS name ON qualified_name opt_drop_behavior
+			| DROP RULE IF_P EXISTS name ON any_name opt_drop_behavior
 				{
-					DropPropertyStmt *n = makeNode(DropPropertyStmt);
-					n->relation = $7;
-					n->property = $5;
-					n->behavior = $8;
+					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_RULE;
+					n->objects = list_make1(lappend($7, makeString($5)));
+					n->arguments = NIL;
+					n->behavior = $8;
 					n->missing_ok = true;
 					$$ = (Node *) n;
 				}
diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c
index 917bb46..3cc159a 100644
--- a/src/backend/rewrite/rewriteRemove.c
+++ b/src/backend/rewrite/rewriteRemove.c
@@ -30,71 +30,6 @@
 #include "utils/syscache.h"
 #include "utils/tqual.h"
 
-
-/*
- * RemoveRewriteRule
- *
- * Delete a rule given its name.
- */
-void
-RemoveRewriteRule(RangeVar *relation, const char *ruleName,
-				  DropBehavior behavior, bool missing_ok)
-{
-	HeapTuple	tuple;
-	Oid			eventRelationOid;
-	Oid			owningRel;
-	ObjectAddress object;
-
-	/* should match RemoveRewriteRuleById */
-	owningRel = RangeVarGetRelid(relation, ShareUpdateExclusiveLock,
-								 false, false);
-
-	/*
-	 * Find the tuple for the target rule.
-	 */
-	tuple = SearchSysCache2(RULERELNAME,
-							ObjectIdGetDatum(owningRel),
-							PointerGetDatum(ruleName));
-
-	/*
-	 * complain if no rule with such name exists
-	 */
-	if (!HeapTupleIsValid(tuple))
-	{
-		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.
-	 */
-	eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
-	Assert(eventRelationOid == owningRel);
-	if (!pg_class_ownercheck(eventRelationOid, GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
-					   get_rel_name(eventRelationOid));
-
-	/*
-	 * Do the deletion
-	 */
-	object.classId = RewriteRelationId;
-	object.objectId = HeapTupleGetOid(tuple);
-	object.objectSubId = 0;
-
-	ReleaseSysCache(tuple);
-
-	performDeletion(&object, behavior);
-}
-
-
 /*
  * Guts of rule deletion.
  */
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index a74019a..ac02dc3 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -204,16 +204,10 @@ check_xact_readonly(Node *parsetree)
 		case T_CreateEnumStmt:
 		case T_AlterEnumStmt:
 		case T_ViewStmt:
-		case T_DropCastStmt:
 		case T_DropStmt:
 		case T_DropdbStmt:
 		case T_DropTableSpaceStmt:
-		case T_RemoveFuncStmt:
 		case T_DropRoleStmt:
-		case T_DropPLangStmt:
-		case T_RemoveOpClassStmt:
-		case T_RemoveOpFamilyStmt:
-		case T_DropPropertyStmt:
 		case T_GrantStmt:
 		case T_GrantRoleStmt:
 		case T_AlterDefaultPrivilegesStmt:
@@ -227,10 +221,8 @@ check_xact_readonly(Node *parsetree)
 		case T_AlterExtensionContentsStmt:
 		case T_CreateFdwStmt:
 		case T_AlterFdwStmt:
-		case T_DropFdwStmt:
 		case T_CreateForeignServerStmt:
 		case T_AlterForeignServerStmt:
-		case T_DropForeignServerStmt:
 		case T_CreateUserMappingStmt:
 		case T_AlterUserMappingStmt:
 		case T_DropUserMappingStmt:
@@ -615,10 +607,6 @@ standard_ProcessUtility(Node *parsetree,
 			AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
 			break;
 
-		case T_DropFdwStmt:
-			RemoveForeignDataWrapper((DropFdwStmt *) parsetree);
-			break;
-
 		case T_CreateForeignServerStmt:
 			CreateForeignServer((CreateForeignServerStmt *) parsetree);
 			break;
@@ -627,10 +615,6 @@ standard_ProcessUtility(Node *parsetree,
 			AlterForeignServer((AlterForeignServerStmt *) parsetree);
 			break;
 
-		case T_DropForeignServerStmt:
-			RemoveForeignServer((DropForeignServerStmt *) parsetree);
-			break;
-
 		case T_CreateUserMappingStmt:
 			CreateUserMapping((CreateUserMappingStmt *) parsetree);
 			break;
@@ -942,29 +926,6 @@ standard_ProcessUtility(Node *parsetree,
 			AlterSequence((AlterSeqStmt *) parsetree);
 			break;
 
-		case T_RemoveFuncStmt:
-			{
-				RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
-
-				switch (stmt->kind)
-				{
-					case OBJECT_FUNCTION:
-						RemoveFunction(stmt);
-						break;
-					case OBJECT_AGGREGATE:
-						RemoveAggregate(stmt);
-						break;
-					case OBJECT_OPERATOR:
-						RemoveOperator(stmt);
-						break;
-					default:
-						elog(ERROR, "unrecognized object type: %d",
-							 (int) stmt->kind);
-						break;
-				}
-			}
-			break;
-
 		case T_DoStmt:
 			ExecuteDoStmt((DoStmt *) parsetree);
 			break;
@@ -1074,38 +1035,10 @@ standard_ProcessUtility(Node *parsetree,
 								 InvalidOid, InvalidOid, false);
 			break;
 
-		case T_DropPropertyStmt:
-			{
-				DropPropertyStmt *stmt = (DropPropertyStmt *) parsetree;
-
-				switch (stmt->removeType)
-				{
-					case OBJECT_RULE:
-						/* RemoveRewriteRule checks permissions */
-						RemoveRewriteRule(stmt->relation, stmt->property,
-										  stmt->behavior, stmt->missing_ok);
-						break;
-					case OBJECT_TRIGGER:
-						/* DropTrigger checks permissions */
-						DropTrigger(stmt->relation, stmt->property,
-									stmt->behavior, stmt->missing_ok);
-						break;
-					default:
-						elog(ERROR, "unrecognized object type: %d",
-							 (int) stmt->removeType);
-						break;
-				}
-			}
-			break;
-
 		case T_CreatePLangStmt:
 			CreateProceduralLanguage((CreatePLangStmt *) parsetree);
 			break;
 
-		case T_DropPLangStmt:
-			DropProceduralLanguage((DropPLangStmt *) parsetree);
-			break;
-
 			/*
 			 * ******************************** DOMAIN statements ****
 			 */
@@ -1215,10 +1148,6 @@ standard_ProcessUtility(Node *parsetree,
 			CreateCast((CreateCastStmt *) parsetree);
 			break;
 
-		case T_DropCastStmt:
-			DropCast((DropCastStmt *) parsetree);
-			break;
-
 		case T_CreateOpClassStmt:
 			DefineOpClass((CreateOpClassStmt *) parsetree);
 			break;
@@ -1231,14 +1160,6 @@ standard_ProcessUtility(Node *parsetree,
 			AlterOpFamily((AlterOpFamilyStmt *) parsetree);
 			break;
 
-		case T_RemoveOpClassStmt:
-			RemoveOpClass((RemoveOpClassStmt *) parsetree);
-			break;
-
-		case T_RemoveOpFamilyStmt:
-			RemoveOpFamily((RemoveOpFamilyStmt *) parsetree);
-			break;
-
 		case T_AlterTSDictionaryStmt:
 			AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
 			break;
@@ -1669,10 +1590,6 @@ CreateCommandTag(Node *parsetree)
 			tag = "ALTER FOREIGN DATA WRAPPER";
 			break;
 
-		case T_DropFdwStmt:
-			tag = "DROP FOREIGN DATA WRAPPER";
-			break;
-
 		case T_CreateForeignServerStmt:
 			tag = "CREATE SERVER";
 			break;
@@ -1681,10 +1598,6 @@ CreateCommandTag(Node *parsetree)
 			tag = "ALTER SERVER";
 			break;
 
-		case T_DropForeignServerStmt:
-			tag = "DROP SERVER";
-			break;
-
 		case T_CreateUserMappingStmt:
 			tag = "CREATE USER MAPPING";
 			break;
@@ -1749,6 +1662,39 @@ CreateCommandTag(Node *parsetree)
 				case OBJECT_EXTENSION:
 					tag = "DROP EXTENSION";
 					break;
+				case OBJECT_FUNCTION:
+					tag = "DROP FUNCTION";
+					break;
+				case OBJECT_AGGREGATE:
+					tag = "DROP AGGREGATE";
+					break;
+				case OBJECT_OPERATOR:
+					tag = "DROP OPERATOR";
+					break;
+				case OBJECT_LANGUAGE:
+					tag = "DROP LANGUAGE";
+					break;
+				case OBJECT_CAST:
+					tag = "DROP CAST";
+					break;
+				case OBJECT_TRIGGER:
+					tag = "DROP TRIGGER";
+					break;
+				case OBJECT_RULE:
+					tag = "DROP RULE";
+					break;
+				case OBJECT_FDW:
+					tag = "DROP FOREIGN DATA WRAPPER";
+					break;
+				case OBJECT_FOREIGN_SERVER:
+					tag = "DROP SERVER";
+					break;
+				case OBJECT_OPCLASS:
+					tag = "DROP OPERATOR CLASS";
+					break;
+				case OBJECT_OPFAMILY:
+					tag = "DROP OPERATOR FAMILY";
+					break;
 				default:
 					tag = "???";
 			}
@@ -1882,23 +1828,6 @@ CreateCommandTag(Node *parsetree)
 			tag = "ALTER SEQUENCE";
 			break;
 
-		case T_RemoveFuncStmt:
-			switch (((RemoveFuncStmt *) parsetree)->kind)
-			{
-				case OBJECT_FUNCTION:
-					tag = "DROP FUNCTION";
-					break;
-				case OBJECT_AGGREGATE:
-					tag = "DROP AGGREGATE";
-					break;
-				case OBJECT_OPERATOR:
-					tag = "DROP OPERATOR";
-					break;
-				default:
-					tag = "???";
-			}
-			break;
-
 		case T_DoStmt:
 			tag = "DO";
 			break;
@@ -1993,28 +1922,10 @@ CreateCommandTag(Node *parsetree)
 			tag = "CREATE TRIGGER";
 			break;
 
-		case T_DropPropertyStmt:
-			switch (((DropPropertyStmt *) parsetree)->removeType)
-			{
-				case OBJECT_TRIGGER:
-					tag = "DROP TRIGGER";
-					break;
-				case OBJECT_RULE:
-					tag = "DROP RULE";
-					break;
-				default:
-					tag = "???";
-			}
-			break;
-
 		case T_CreatePLangStmt:
 			tag = "CREATE LANGUAGE";
 			break;
 
-		case T_DropPLangStmt:
-			tag = "DROP LANGUAGE";
-			break;
-
 		case T_CreateRoleStmt:
 			tag = "CREATE ROLE";
 			break;
@@ -2063,10 +1974,6 @@ CreateCommandTag(Node *parsetree)
 			tag = "CREATE CAST";
 			break;
 
-		case T_DropCastStmt:
-			tag = "DROP CAST";
-			break;
-
 		case T_CreateOpClassStmt:
 			tag = "CREATE OPERATOR CLASS";
 			break;
@@ -2079,14 +1986,6 @@ CreateCommandTag(Node *parsetree)
 			tag = "ALTER OPERATOR FAMILY";
 			break;
 
-		case T_RemoveOpClassStmt:
-			tag = "DROP OPERATOR CLASS";
-			break;
-
-		case T_RemoveOpFamilyStmt:
-			tag = "DROP OPERATOR FAMILY";
-			break;
-
 		case T_AlterTSDictionaryStmt:
 			tag = "ALTER TEXT SEARCH DICTIONARY";
 			break;
@@ -2297,10 +2196,8 @@ GetCommandLogLevel(Node *parsetree)
 
 		case T_CreateFdwStmt:
 		case T_AlterFdwStmt:
-		case T_DropFdwStmt:
 		case T_CreateForeignServerStmt:
 		case T_AlterForeignServerStmt:
-		case T_DropForeignServerStmt:
 		case T_CreateUserMappingStmt:
 		case T_AlterUserMappingStmt:
 		case T_DropUserMappingStmt:
@@ -2433,10 +2330,6 @@ GetCommandLogLevel(Node *parsetree)
 			lev = LOGSTMT_DDL;
 			break;
 
-		case T_RemoveFuncStmt:
-			lev = LOGSTMT_DDL;
-			break;
-
 		case T_DoStmt:
 			lev = LOGSTMT_ALL;
 			break;
@@ -2520,18 +2413,10 @@ GetCommandLogLevel(Node *parsetree)
 			lev = LOGSTMT_DDL;
 			break;
 
-		case T_DropPropertyStmt:
-			lev = LOGSTMT_DDL;
-			break;
-
 		case T_CreatePLangStmt:
 			lev = LOGSTMT_DDL;
 			break;
 
-		case T_DropPLangStmt:
-			lev = LOGSTMT_DDL;
-			break;
-
 		case T_CreateDomainStmt:
 			lev = LOGSTMT_DDL;
 			break;
@@ -2584,10 +2469,6 @@ GetCommandLogLevel(Node *parsetree)
 			lev = LOGSTMT_DDL;
 			break;
 
-		case T_DropCastStmt:
-			lev = LOGSTMT_DDL;
-			break;
-
 		case T_CreateOpClassStmt:
 			lev = LOGSTMT_DDL;
 			break;
@@ -2600,14 +2481,6 @@ GetCommandLogLevel(Node *parsetree)
 			lev = LOGSTMT_DDL;
 			break;
 
-		case T_RemoveOpClassStmt:
-			lev = LOGSTMT_DDL;
-			break;
-
-		case T_RemoveOpFamilyStmt:
-			lev = LOGSTMT_DDL;
-			break;
-
 		case T_AlterTSDictionaryStmt:
 			lev = LOGSTMT_DDL;
 			break;
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 64eeb73..f0dcf76 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -61,7 +61,6 @@ extern Oid	GetDefaultOpClass(Oid type_id, Oid am_id);
 
 /* commands/functioncmds.c */
 extern void CreateFunction(CreateFunctionStmt *stmt, const char *queryString);
-extern void RemoveFunction(RemoveFuncStmt *stmt);
 extern void RemoveFunctionById(Oid funcOid);
 extern void SetFunctionReturnType(Oid funcOid, Oid newRetType);
 extern void SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType);
@@ -70,7 +69,6 @@ extern void AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId);
 extern void AlterFunctionOwner_oid(Oid procOid, Oid newOwnerId);
 extern void AlterFunction(AlterFunctionStmt *stmt);
 extern void CreateCast(CreateCastStmt *stmt);
-extern void DropCast(DropCastStmt *stmt);
 extern void DropCastById(Oid castOid);
 extern void AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
 					   const char *newschema);
@@ -80,7 +78,6 @@ extern Oid	get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
 
 /* commands/operatorcmds.c */
 extern void DefineOperator(List *names, List *parameters);
-extern void RemoveOperator(RemoveFuncStmt *stmt);
 extern void RemoveOperatorById(Oid operOid);
 extern void AlterOperatorOwner(List *name, TypeName *typeName1,
 				   TypeName *typename2, Oid newOwnerId);
@@ -91,7 +88,6 @@ extern Oid	AlterOperatorNamespace_oid(Oid operOid, Oid newNspOid);
 /* commands/aggregatecmds.c */
 extern void DefineAggregate(List *name, List *args, bool oldstyle,
 				List *parameters);
-extern void RemoveAggregate(RemoveFuncStmt *stmt);
 extern void RenameAggregate(List *name, List *args, const char *newname);
 extern void AlterAggregateOwner(List *name, List *args, Oid newOwnerId);
 
@@ -99,8 +95,6 @@ extern void AlterAggregateOwner(List *name, List *args, Oid newOwnerId);
 extern void DefineOpClass(CreateOpClassStmt *stmt);
 extern void DefineOpFamily(CreateOpFamilyStmt *stmt);
 extern void AlterOpFamily(AlterOpFamilyStmt *stmt);
-extern void RemoveOpClass(RemoveOpClassStmt *stmt);
-extern void RemoveOpFamily(RemoveOpFamilyStmt *stmt);
 extern void RemoveOpClassById(Oid opclassOid);
 extern void RemoveOpFamilyById(Oid opfamilyOid);
 extern void RemoveAmOpEntryById(Oid entryOid);
@@ -156,11 +150,9 @@ extern void AlterForeignServerOwner(const char *name, Oid newOwnerId);
 extern void AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId);
 extern void CreateForeignDataWrapper(CreateFdwStmt *stmt);
 extern void AlterForeignDataWrapper(AlterFdwStmt *stmt);
-extern void RemoveForeignDataWrapper(DropFdwStmt *stmt);
 extern void RemoveForeignDataWrapperById(Oid fdwId);
 extern void CreateForeignServer(CreateForeignServerStmt *stmt);
 extern void AlterForeignServer(AlterForeignServerStmt *stmt);
-extern void RemoveForeignServer(DropForeignServerStmt *stmt);
 extern void RemoveForeignServerById(Oid srvId);
 extern void CreateUserMapping(CreateUserMappingStmt *stmt);
 extern void AlterUserMapping(AlterUserMappingStmt *stmt);
diff --git a/src/include/commands/proclang.h b/src/include/commands/proclang.h
index 644c371..17d0972 100644
--- a/src/include/commands/proclang.h
+++ b/src/include/commands/proclang.h
@@ -15,7 +15,6 @@
 #include "nodes/parsenodes.h"
 
 extern void CreateProceduralLanguage(CreatePLangStmt *stmt);
-extern void DropProceduralLanguage(DropPLangStmt *stmt);
 extern void DropProceduralLanguageById(Oid langOid);
 extern void RenameLanguage(const char *oldname, const char *newname);
 extern void AlterLanguageOwner(const char *name, Oid newOwnerId);
diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h
index fe21298..e7d28f7 100644
--- a/src/include/commands/trigger.h
+++ b/src/include/commands/trigger.h
@@ -112,8 +112,6 @@ extern Oid CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 			  Oid constraintOid, Oid indexOid,
 			  bool isInternal);
 
-extern void DropTrigger(RangeVar *relation, const char *trigname,
-			DropBehavior behavior, bool missing_ok);
 extern void RemoveTriggerById(Oid trigOid);
 extern Oid	get_trigger_oid(Oid relid, const char *name, bool missing_ok);
 
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 7aa2994..9405d44 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -291,7 +291,6 @@ typedef enum NodeTag
 	T_IndexStmt,
 	T_CreateFunctionStmt,
 	T_AlterFunctionStmt,
-	T_RemoveFuncStmt,
 	T_DoStmt,
 	T_RenameStmt,
 	T_RuleStmt,
@@ -312,9 +311,7 @@ typedef enum NodeTag
 	T_VariableShowStmt,
 	T_DiscardStmt,
 	T_CreateTrigStmt,
-	T_DropPropertyStmt,
 	T_CreatePLangStmt,
-	T_DropPLangStmt,
 	T_CreateRoleStmt,
 	T_AlterRoleStmt,
 	T_DropRoleStmt,
@@ -328,12 +325,9 @@ typedef enum NodeTag
 	T_AlterRoleSetStmt,
 	T_CreateConversionStmt,
 	T_CreateCastStmt,
-	T_DropCastStmt,
 	T_CreateOpClassStmt,
 	T_CreateOpFamilyStmt,
 	T_AlterOpFamilyStmt,
-	T_RemoveOpClassStmt,
-	T_RemoveOpFamilyStmt,
 	T_PrepareStmt,
 	T_ExecuteStmt,
 	T_DeallocateStmt,
@@ -351,10 +345,8 @@ typedef enum NodeTag
 	T_AlterTSConfigurationStmt,
 	T_CreateFdwStmt,
 	T_AlterFdwStmt,
-	T_DropFdwStmt,
 	T_CreateForeignServerStmt,
 	T_AlterForeignServerStmt,
-	T_DropForeignServerStmt,
 	T_CreateUserMappingStmt,
 	T_AlterUserMappingStmt,
 	T_DropUserMappingStmt,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 9998e2f..5029304 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1612,7 +1612,7 @@ typedef struct AlterExtensionContentsStmt
 } AlterExtensionContentsStmt;
 
 /* ----------------------
- *		Create/Drop FOREIGN DATA WRAPPER Statements
+ *		Create/Alter FOREIGN DATA WRAPPER Statements
  * ----------------------
  */
 
@@ -1632,16 +1632,8 @@ typedef struct AlterFdwStmt
 	List	   *options;		/* generic options to FDW */
 } AlterFdwStmt;
 
-typedef struct DropFdwStmt
-{
-	NodeTag		type;
-	char	   *fdwname;		/* foreign-data wrapper name */
-	bool		missing_ok;		/* don't complain if missing */
-	DropBehavior behavior;		/* drop behavior - cascade/restrict */
-} DropFdwStmt;
-
 /* ----------------------
- *		Create/Drop FOREIGN SERVER Statements
+ *		Create/Alter FOREIGN SERVER Statements
  * ----------------------
  */
 
@@ -1664,14 +1656,6 @@ typedef struct AlterForeignServerStmt
 	bool		has_version;	/* version specified */
 } AlterForeignServerStmt;
 
-typedef struct DropForeignServerStmt
-{
-	NodeTag		type;
-	char	   *servername;		/* server name */
-	bool		missing_ok;		/* ignore missing servers */
-	DropBehavior behavior;		/* drop behavior - cascade/restrict */
-} DropForeignServerStmt;
-
 /* ----------------------
  *		Create FOREIGN TABLE Statements
  * ----------------------
@@ -1739,7 +1723,7 @@ typedef struct CreateTrigStmt
 } CreateTrigStmt;
 
 /* ----------------------
- *		Create/Drop PROCEDURAL LANGUAGE Statements
+ *		Create PROCEDURAL LANGUAGE Statements
  * ----------------------
  */
 typedef struct CreatePLangStmt
@@ -1753,14 +1737,6 @@ typedef struct CreatePLangStmt
 	bool		pltrusted;		/* PL is trusted */
 } CreatePLangStmt;
 
-typedef struct DropPLangStmt
-{
-	NodeTag		type;
-	char	   *plname;			/* PL name */
-	DropBehavior behavior;		/* RESTRICT or CASCADE behavior */
-	bool		missing_ok;		/* skip error if missing? */
-} DropPLangStmt;
-
 /* ----------------------
  *	Create/Alter/Drop Role Statements
  *
@@ -1921,30 +1897,13 @@ typedef struct DropStmt
 {
 	NodeTag		type;
 	List	   *objects;		/* list of sublists of names (as Values) */
+	List	   *arguments;		/* list of sublists of arguments (as Values) */
 	ObjectType	removeType;		/* object type */
 	DropBehavior behavior;		/* RESTRICT or CASCADE behavior */
 	bool		missing_ok;		/* skip error if object is missing? */
 } DropStmt;
 
 /* ----------------------
- *		Drop Rule|Trigger Statement
- *
- * In general this may be used for dropping any property of a relation;
- * for example, someday soon we may have DROP ATTRIBUTE.
- * ----------------------
- */
-
-typedef struct DropPropertyStmt
-{
-	NodeTag		type;
-	RangeVar   *relation;		/* owning relation */
-	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 missing? */
-} DropPropertyStmt;
-
-/* ----------------------
  *				Truncate Table Statement
  * ----------------------
  */
@@ -2118,20 +2077,6 @@ typedef struct AlterFunctionStmt
 } AlterFunctionStmt;
 
 /* ----------------------
- *		Drop {Function|Aggregate|Operator} Statement
- * ----------------------
- */
-typedef struct RemoveFuncStmt
-{
-	NodeTag		type;
-	ObjectType	kind;			/* function, aggregate, operator */
-	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 missing? */
-} RemoveFuncStmt;
-
-/* ----------------------
  *		DO Statement
  *
  * DoStmt is the raw parser output, InlineCodeBlock is the execution-time API
@@ -2152,32 +2097,6 @@ typedef struct InlineCodeBlock
 } InlineCodeBlock;
 
 /* ----------------------
- *		Drop Operator Class Statement
- * ----------------------
- */
-typedef struct RemoveOpClassStmt
-{
-	NodeTag		type;
-	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 missing? */
-} RemoveOpClassStmt;
-
-/* ----------------------
- *		Drop Operator Family Statement
- * ----------------------
- */
-typedef struct RemoveOpFamilyStmt
-{
-	NodeTag		type;
-	List	   *opfamilyname;	/* qualified name (list of Value strings) */
-	char	   *amname;			/* name of index AM opfamily is for */
-	DropBehavior behavior;		/* RESTRICT or CASCADE behavior */
-	bool		missing_ok;		/* skip error if missing? */
-} RemoveOpFamilyStmt;
-
-/* ----------------------
  *		Alter Object Rename Statement
  * ----------------------
  */
@@ -2547,20 +2466,6 @@ typedef struct CreateCastStmt
 } CreateCastStmt;
 
 /* ----------------------
- *	DROP CAST Statement
- * ----------------------
- */
-typedef struct DropCastStmt
-{
-	NodeTag		type;
-	TypeName   *sourcetype;
-	TypeName   *targettype;
-	DropBehavior behavior;
-	bool		missing_ok;		/* skip error if missing? */
-} DropCastStmt;
-
-
-/* ----------------------
  *		PREPARE Statement
  * ----------------------
  */
diff --git a/src/include/rewrite/rewriteRemove.h b/src/include/rewrite/rewriteRemove.h
index b9a63ba..14f3c1d 100644
--- a/src/include/rewrite/rewriteRemove.h
+++ b/src/include/rewrite/rewriteRemove.h
@@ -16,9 +16,6 @@
 
 #include "nodes/parsenodes.h"
 
-
-extern void RemoveRewriteRule(RangeVar *relation, const char *ruleName,
-				  DropBehavior behavior, bool missing_ok);
 extern void RemoveRewriteRuleById(Oid ruleOid);
 
 #endif   /* REWRITEREMOVE_H */
diff --git a/src/test/regress/expected/drop_if_exists.out b/src/test/regress/expected/drop_if_exists.out
index d290776..8599401 100644
--- a/src/test/regress/expected/drop_if_exists.out
+++ b/src/test/regress/expected/drop_if_exists.out
@@ -214,7 +214,7 @@ ERROR:  access method "no_such_am" does not exist
 DROP OPERATOR FAMILY test_operator_family USING btree;
 ERROR:  operator family "test_operator_family" does not exist for access method "btree"
 DROP OPERATOR FAMILY IF EXISTS test_operator_family USING btree;
-ERROR:  operator family "test_operator_family" does not exist for access method "btree"
+NOTICE:  operator family "test_operator_family" does not exist for access method "btree", skipping
 DROP OPERATOR FAMILY test_operator_family USING no_such_am;
 ERROR:  access method "no_such_am" does not exist
 DROP OPERATOR FAMILY IF EXISTS test_operator_family USING no_such_am;