>From 9fec4a4e81313e08c002ddbb38207fa41213dee8 Mon Sep 17 00:00:00 2001
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Date: Tue, 23 Sep 2014 17:39:03 -0300
Subject: [PATCH 29/30] deparse: Support COMMENT ON

---
 src/backend/commands/comment.c       |  5 ++++-
 src/backend/commands/event_trigger.c |  1 +
 src/backend/tcop/deparse_utility.c   | 31 +++++++++++++++++++++++++++++++
 src/backend/tcop/utility.c           | 28 ++++++++++++++++++++++++----
 src/include/commands/comment.h       |  2 +-
 5 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index 34f6cae..59781e5 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -37,7 +37,7 @@
  * pg_description for the object specified by the given SQL command.
  */
 Oid
-CommentObject(CommentStmt *stmt)
+CommentObject(CommentStmt *stmt, uint32 *objectSubId)
 {
 	ObjectAddress address;
 	Relation	relation;
@@ -126,6 +126,9 @@ CommentObject(CommentStmt *stmt)
 	if (relation != NULL)
 		relation_close(relation, NoLock);
 
+	if (objectSubId)
+		*objectSubId = address.objectSubId;
+
 	return address.objectId;
 }
 
diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index b7d879a..0c0f926 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -257,6 +257,7 @@ check_ddl_tag(const char *tag)
 		pg_strcasecmp(tag, "REFRESH MATERIALIZED VIEW") == 0 ||
 		pg_strcasecmp(tag, "ALTER DEFAULT PRIVILEGES") == 0 ||
 		pg_strcasecmp(tag, "ALTER LARGE OBJECT") == 0 ||
+		pg_strcasecmp(tag, "COMMENT") == 0 ||
 		pg_strcasecmp(tag, "GRANT") == 0 ||
 		pg_strcasecmp(tag, "REVOKE") == 0 ||
 		pg_strcasecmp(tag, "DROP OWNED") == 0 ||
diff --git a/src/backend/tcop/deparse_utility.c b/src/backend/tcop/deparse_utility.c
index de63baa..9c02626 100644
--- a/src/backend/tcop/deparse_utility.c
+++ b/src/backend/tcop/deparse_utility.c
@@ -3886,6 +3886,33 @@ deparse_AlterOwnerStmt(Oid objectId, Node *parsetree)
 }
 
 static char *
+deparse_CommentStmt(Oid objectId, Oid objectSubId, Node *parsetree)
+{
+	CommentStmt *node = (CommentStmt *) parsetree;
+	ObjTree	   *comment;
+	ObjectAddress addr;
+	char	   *fmt;
+	char	   *command;
+
+	fmt = psprintf("COMMENT ON %s %%{identity}s IS %%{comment}L",
+				   stringify_objtype(node->objtype));
+	comment = new_objtree_VA(fmt, 0);
+	append_string_object(comment, "comment", node->comment);
+
+	addr.classId = get_objtype_catalog_oid(node->objtype);
+	addr.objectId = objectId;
+	addr.objectSubId = objectSubId;
+
+	append_string_object(comment, "identity",
+						 getObjectIdentity(&addr));
+
+	command = jsonize_objtree(comment);
+	free_objtree(comment);
+
+	return command;
+}
+
+static char *
 deparse_CreateConversion(Oid objectId, Node *parsetree)
 {
 	HeapTuple   conTup;
@@ -4725,6 +4752,10 @@ deparse_parsenode_cmd(StashedCommand *cmd)
 			command = deparse_AlterOwnerStmt(objectId, parsetree);
 			break;
 
+		case T_CommentStmt:
+			command = deparse_CommentStmt(objectId, objectSubId, parsetree);
+			break;
+
 		case T_GrantStmt:
 			/* GRANT/REVOKE are implemented separately */
 			elog(ERROR, "unexpected node type T_GrantStmt");
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 7c0b271..388157f 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -512,10 +512,6 @@ standard_ProcessUtility(Node *parsetree,
 			ExecuteTruncate((TruncateStmt *) parsetree);
 			break;
 
-		case T_CommentStmt:
-			CommentObject((CommentStmt *) parsetree);
-			break;
-
 		case T_SecLabelStmt:
 			ExecSecLabelStmt((SecLabelStmt *) parsetree);
 			break;
@@ -828,6 +824,19 @@ standard_ProcessUtility(Node *parsetree,
 			}
 			break;
 
+		case T_CommentStmt:
+			{
+				CommentStmt *stmt = (CommentStmt *) parsetree;
+
+				if (EventTriggerSupportsObjectType(stmt->objtype))
+					ProcessUtilitySlow(parsetree, queryString,
+									   context, params,
+									   dest, completionTag);
+				else
+					CommentObject((CommentStmt *) parsetree, NULL);
+				break;
+			}
+
 		default:
 			/* All other statement types have event trigger support */
 			ProcessUtilitySlow(parsetree, queryString,
@@ -1390,6 +1399,17 @@ ProcessUtilitySlow(Node *parsetree,
 										 parsetree);
 				break;
 
+			case T_CommentStmt:
+				{
+					uint32	objectSubId;
+
+					objectId = CommentObject((CommentStmt *) parsetree, &objectSubId);
+					EventTriggerStashCommand(objectId, objectSubId,
+											 ((CommentStmt *) parsetree)->objtype,
+											 parsetree);
+					break;
+				}
+
 			case T_GrantStmt:
 				/* command is stashed in ExecuteGrantStmt_oids */
 				ExecuteGrantStmt((GrantStmt *) parsetree);
diff --git a/src/include/commands/comment.h b/src/include/commands/comment.h
index 05fe0c6..46a6fa9 100644
--- a/src/include/commands/comment.h
+++ b/src/include/commands/comment.h
@@ -29,7 +29,7 @@
  *------------------------------------------------------------------
  */
 
-extern Oid	CommentObject(CommentStmt *stmt);
+extern Oid	CommentObject(CommentStmt *stmt, uint32 *objectSubId);
 
 extern void DeleteComments(Oid oid, Oid classoid, int32 subid);
 
-- 
1.9.1

