>From aefc63f845900445d04c60f4ce73d8f1a92c9d97 Mon Sep 17 00:00:00 2001
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Date: Mon, 9 Feb 2015 20:41:51 -0300
Subject: [PATCH 32/42] deparse: support ALTER EXTENSION ADD/DROP

---
 src/backend/commands/extension.c   |  6 +++++-
 src/backend/tcop/deparse_utility.c | 27 ++++++++++++++++++++++++++-
 src/backend/tcop/utility.c         |  5 +++--
 src/include/commands/extension.h   |  3 ++-
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 14be4cd..4b28a8d 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -2885,7 +2885,7 @@ ApplyExtensionUpdates(Oid extensionOid,
  * Execute ALTER EXTENSION ADD/DROP
  */
 Oid
-ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt)
+ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt, Oid *objectId)
 {
 	ObjectAddress extension;
 	ObjectAddress object;
@@ -2910,6 +2910,10 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt)
 	object = get_object_address(stmt->objtype, stmt->objname, stmt->objargs,
 								&relation, ShareUpdateExclusiveLock, false);
 
+	Assert(object.objectSubId == 0);
+	if (objectId)
+		*objectId = object.objectId;
+
 	/* Permission check: must own target object, too */
 	check_object_ownership(GetUserId(), stmt->objtype, object,
 						   stmt->objname, stmt->objargs, relation);
diff --git a/src/backend/tcop/deparse_utility.c b/src/backend/tcop/deparse_utility.c
index a813f94..cefea83 100644
--- a/src/backend/tcop/deparse_utility.c
+++ b/src/backend/tcop/deparse_utility.c
@@ -1682,6 +1682,30 @@ deparse_AlterDomainStmt(Oid objectId, Node *parsetree, Oid secondaryOid)
 }
 
 static ObjTree *
+deparse_AlterExtensionContentsStmt(Oid objectId, Node *parsetree, Oid secondaryOid)
+{
+	AlterExtensionContentsStmt *node = (AlterExtensionContentsStmt *) parsetree;
+	ObjTree	   *stmt;
+	char	   *fmt;
+	ObjectAddress addr;
+
+	Assert(node->action == +1 || node->action == -1);
+
+	fmt = psprintf("ALTER EXTENSION %%{extidentity}I %s %s %%{objidentity}s",
+				   node->action == +1 ? "ADD" : "DROP",
+				   stringify_objtype(node->objtype));
+	addr.classId = get_objtype_catalog_oid(node->objtype);
+	addr.objectId = secondaryOid;
+	addr.objectSubId = 0;
+
+	stmt = new_objtree_VA(fmt, 2, "extidentity", ObjTypeString, node->extname,
+						  "objidentity", ObjTypeString,
+						  getObjectIdentity(&addr));
+
+	return stmt;
+}
+
+static ObjTree *
 deparse_AlterExtensionStmt(Oid objectId, Node *parsetree)
 {
 	AlterExtensionStmt *node = (AlterExtensionStmt *) parsetree;
@@ -5099,7 +5123,8 @@ deparse_simple_command(StashedCommand *cmd)
 			break;
 
 		case T_AlterExtensionContentsStmt:
-			elog(ERROR, "unimplemented deparse of %s", CreateCommandTag(parsetree));
+			command = deparse_AlterExtensionContentsStmt(objectId, parsetree,
+														 cmd->d.simple.secondaryOid);
 			break;
 
 		case T_CreateFdwStmt:
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 438ee9b..a06b901 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1248,8 +1248,9 @@ ProcessUtilitySlow(Node *parsetree,
 				break;
 
 			case T_AlterExtensionContentsStmt:
-				objectId = ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree);
-				EventTriggerStashCommand(objectId, 0, OBJECT_EXTENSION, InvalidOid, parsetree);
+				objectId = ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree,
+														  &secondaryOid);
+				EventTriggerStashCommand(objectId, 0, OBJECT_EXTENSION, secondaryOid, parsetree);
 				break;
 
 			case T_CreateFdwStmt:
diff --git a/src/include/commands/extension.h b/src/include/commands/extension.h
index f678950..b3b73cc 100644
--- a/src/include/commands/extension.h
+++ b/src/include/commands/extension.h
@@ -38,7 +38,8 @@ extern Oid InsertExtensionTuple(const char *extName, Oid extOwner,
 
 extern Oid	ExecAlterExtensionStmt(AlterExtensionStmt *stmt);
 
-extern Oid	ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt);
+extern Oid	ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt,
+							   Oid *objectId);
 
 extern Oid	get_extension_oid(const char *extname, bool missing_ok);
 extern char *get_extension_name(Oid ext_oid);
-- 
2.1.4

