From 87fd33209271d23ada1cc9e9d0a42d5535ba191f Mon Sep 17 00:00:00 2001
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Date: Thu, 25 Sep 2014 14:34:00 -0300
Subject: [PATCH 14/29] deparse: Support CREATE VIEW

---
 src/backend/tcop/deparse_utility.c | 38 +++++++++++++++++++++++++++++++++++++-
 src/backend/utils/adt/ruleutils.c  |  7 +++++++
 src/include/utils/ruleutils.h      |  1 +
 3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/src/backend/tcop/deparse_utility.c b/src/backend/tcop/deparse_utility.c
index 96b16dc..a51c6dc 100644
--- a/src/backend/tcop/deparse_utility.c
+++ b/src/backend/tcop/deparse_utility.c
@@ -917,6 +917,42 @@ deparse_AlterDomainStmt(Oid objectId, Node *parsetree,
 }
 
 /*
+ * deparse_ViewStmt
+ *		deparse a ViewStmt
+ *
+ * Given a view OID and the parsetree that created it, return an ObjTree
+ * representing the creation command.
+ */
+static ObjTree *
+deparse_ViewStmt(Oid objectId, Node *parsetree)
+{
+	ViewStmt   *node = (ViewStmt *) parsetree;
+	ObjTree    *viewStmt;
+	ObjTree    *tmp;
+	Relation	relation;
+
+	relation = relation_open(objectId, AccessShareLock);
+
+	viewStmt = new_objtree_VA("CREATE %{or_replace}s %{persistence}s VIEW %{identity}D AS %{query}s",
+							  2,
+							  "or_replace", ObjTypeString,
+							  node->replace ? "OR REPLACE" : "",
+							  "persistence", ObjTypeString,
+					  get_persistence_str(relation->rd_rel->relpersistence));
+
+	tmp = new_objtree_for_qualname(relation->rd_rel->relnamespace,
+								   RelationGetRelationName(relation));
+	append_object_object(viewStmt, "identity", tmp);
+
+	append_string_object(viewStmt, "query",
+						 pg_get_viewdef_internal(objectId));
+
+	relation_close(relation, AccessShareLock);
+
+	return viewStmt;
+}
+
+/*
  * deparse_CreateTrigStmt
  *		Deparse a CreateTrigStmt (CREATE TRIGGER)
  *
@@ -4116,7 +4152,7 @@ deparse_simple_command(StashedCommand *cmd)
 			break;
 
 		case T_ViewStmt:		/* CREATE VIEW */
-			elog(ERROR, "unimplemented deparse of %s", CreateCommandTag(parsetree));
+			command = deparse_ViewStmt(objectId, parsetree);
 			break;
 
 		case T_CreateFunctionStmt:
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 7fbd4f9..1a2f03c 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -669,6 +669,13 @@ pg_get_viewdef_name_ext(PG_FUNCTION_ARGS)
 	PG_RETURN_TEXT_P(string_to_text(pg_get_viewdef_worker(viewoid, prettyFlags, WRAP_COLUMN_DEFAULT)));
 }
 
+char *
+pg_get_viewdef_internal(Oid viewoid)
+{
+	return pg_get_viewdef_worker(viewoid, 0, WRAP_COLUMN_DEFAULT);
+}
+
+
 /*
  * Common code for by-OID and by-name variants of pg_get_viewdef
  */
diff --git a/src/include/utils/ruleutils.h b/src/include/utils/ruleutils.h
index ce6a1b1..7b22ea0 100644
--- a/src/include/utils/ruleutils.h
+++ b/src/include/utils/ruleutils.h
@@ -32,6 +32,7 @@ extern char *pg_get_trigger_whenclause(Form_pg_trigger trigrec,
 extern char *pg_get_constraintdef_string(Oid constraintId, bool fullCommand);
 extern void pg_get_ruledef_details(Datum ev_qual, Datum ev_action,
 					   char **whereClause, List **actions);
+extern char *pg_get_viewdef_internal(Oid viewoid);
 
 extern char *deparse_expression(Node *expr, List *dpcontext,
 				   bool forceprefix, bool showimplicit);
-- 
2.1.4

