>From 7e6ba04f038b205f1527277cff2f50a326a902f1 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sat, 21 Feb 2015 16:36:34 +0100
Subject: [PATCH 3/3] fixup! deparse: Support CREATE FUNCTION

Add SET support.
---
 src/backend/tcop/deparse_utility.c | 55 +++++++++++++++++++++++++++++++++++---
 1 file changed, 52 insertions(+), 3 deletions(-)

diff --git a/src/backend/tcop/deparse_utility.c b/src/backend/tcop/deparse_utility.c
index 35c4eca..4abf6fa 100644
--- a/src/backend/tcop/deparse_utility.c
+++ b/src/backend/tcop/deparse_utility.c
@@ -3089,7 +3089,58 @@ deparse_CreateFunction(Oid objectId, Node *parsetree)
 		append_float_object(tmp, "rows", procForm->prorows);
 	append_object_object(createFunc, "rows", tmp);
 
-	append_array_object(createFunc, "set_options", NIL);
+	tmpdatum = SysCacheGetAttr(PROCOID, procTup,
+							   Anum_pg_proc_proconfig, &isnull);
+	if (!isnull)
+	{
+		List	   *sets = NIL;
+		ArrayType  *a = DatumGetArrayTypeP(tmpdatum);
+		int			i;
+
+		Assert(ARR_ELEMTYPE(a) == TEXTOID);
+		Assert(ARR_NDIM(a) == 1);
+		Assert(ARR_LBOUND(a)[0] == 1);
+
+		for (i = 1; i <= ARR_DIMS(a)[0]; i++)
+		{
+			Datum		d;
+
+			d = array_ref(a, 1, &i,
+						  -1 /* varlenarray */ ,
+						  -1 /* TEXT's typlen */ ,
+						  false /* TEXT's typbyval */ ,
+						  'i' /* TEXT's typalign */ ,
+						  &isnull);
+			if (!isnull)
+			{
+				char	   *configitem = TextDatumGetCString(d);
+				char	   *pos;
+				ObjTree	   *oneset;
+
+				pos = strchr(configitem, '=');
+				if (pos == NULL)
+					continue;
+				*pos++ = '\0';
+
+				/*
+				 * Some GUC variable names are 'LIST' type and hence must not
+				 * be quoted. FIXME: shouldn't this and pg_get_functiondef()
+				 * rather use guc.c to check for GUC_LIST?
+				 */
+				if (pg_strcasecmp(configitem, "DateStyle") == 0
+					|| pg_strcasecmp(configitem, "search_path") == 0)
+					oneset = new_objtree_VA("SET %{set_name}I TO %{set_value}s", 0);
+				else
+					oneset = new_objtree_VA("SET %{set_name}I TO %{set_value}L", 0);
+
+				append_string_object(oneset, "set_name", configitem);
+				append_string_object(oneset, "set_value", pos);
+
+				sets = lappend(sets, new_object_object(oneset));
+			}
+		}
+		append_array_object(createFunc, "set_options", sets);
+	}
 
 	if (probin == NULL)
 	{
@@ -3114,8 +3165,6 @@ deparse_CreateFunction(Oid objectId, Node *parsetree)
  *
  * Given a function OID and the parsetree that created it, return the JSON
  * blob representing the alter command.
- *
- * XXX this is missing the per-function custom-GUC thing.
  */
 static ObjTree *
 deparse_AlterFunction(Oid objectId, Node *parsetree)
-- 
2.3.0.149.gf3f4077.dirty

