On 2015-02-21 17:30:24 +0100, Andres Freund wrote:

> >  /*
> > + * deparse_CreateFunctionStmt
> > + *         Deparse a CreateFunctionStmt (CREATE FUNCTION)
> > + *
> > + * Given a function OID and the parsetree that created it, return the JSON
> > + * blob representing the creation command.
> > + *
> > + * XXX this is missing the per-function custom-GUC thing.
> > + */

> > Subject: [PATCH 27/42] deparse: Support ALTER FUNCTION
> 
> > + * deparse_AlterFunctionStmt
> > + *         Deparse a AlterFunctionStmt (ALTER FUNCTION)
> > + *
> > + * 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.
> > + */
> 
> Hm, so my earlier ptatch needs to partially be copied here. I'm running out 
> of time now though...

Updated 0003 attached that supports both SET for both CREATE and
ALTER. In my previous patch I'd looked at proconfig for the values. A
bit further thought revealed that that's not such a great idea: It works
well enough for CREATE FUNCTION, but already breaks down at CREATE OR
REPLACE FUNCTION unless we want to emit RESET ALL (SET ...)+ which seems
mighty ugly.

Also, the code is actually a good bit easier to understand this
way. I. hate. arrays. ;)

Greetings,

Andres Freund

-- 
 Andres Freund                     http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services
>From bb8b0027e82e628fb098b9707f36fa5ce08b9234 Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Sat, 21 Feb 2015 16:36:34 +0100
Subject: [PATCH 3/3] Support SET/RESET in CREATE/ALTER FUNCTION.

---
 src/backend/tcop/deparse_utility.c | 61 ++++++++++++++++++++++++++++++++++----
 1 file changed, 55 insertions(+), 6 deletions(-)

diff --git a/src/backend/tcop/deparse_utility.c b/src/backend/tcop/deparse_utility.c
index 35c4eca..cb52cb2 100644
--- a/src/backend/tcop/deparse_utility.c
+++ b/src/backend/tcop/deparse_utility.c
@@ -2802,14 +2802,46 @@ deparse_CreateDomain(Oid objectId, Node *parsetree)
 	return createDomain;
 }
 
+static ObjTree *
+deparse_FunctionSet(VariableSetKind kind, char *name, char *value)
+{
+	ObjTree	   *r;
+
+	if (kind == VAR_RESET_ALL)
+	{
+		r = new_objtree_VA("RESET ALL", 0);
+	}
+	else if (value != NULL)
+	{
+		/*
+		 * 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(name, "DateStyle") == 0
+			|| pg_strcasecmp(name, "search_path") == 0)
+			r = new_objtree_VA("SET %{set_name}I TO %{set_value}s", 0);
+		else
+			r = new_objtree_VA("SET %{set_name}I TO %{set_value}L", 0);
+
+		append_string_object(r, "set_name", name);
+		append_string_object(r, "set_value", value);
+	}
+	else
+	{
+		r = new_objtree_VA("RESET %{set_name}I", 0);
+		append_string_object(r, "set_name", name);
+	}
+
+	return r;
+}
+
 /*
  * deparse_CreateFunctionStmt
  *		Deparse a CreateFunctionStmt (CREATE FUNCTION)
  *
  * Given a function OID and the parsetree that created it, return the JSON
  * blob representing the creation command.
- *
- * XXX this is missing the per-function custom-GUC thing.
  */
 static ObjTree *
 deparse_CreateFunction(Oid objectId, Node *parsetree)
@@ -2825,6 +2857,7 @@ deparse_CreateFunction(Oid objectId, Node *parsetree)
 	char	   *probin;
 	List	   *params;
 	List	   *defaults;
+	List	   *sets = NIL;
 	ListCell   *cell;
 	ListCell   *curdef;
 	ListCell   *table_params = NULL;
@@ -3089,7 +3122,21 @@ 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);
+	foreach(cell, node->options)
+	{
+		DefElem	*defel = (DefElem *) lfirst(cell);
+		ObjTree	   *tmp = NULL;
+
+		if (strcmp(defel->defname, "set") == 0)
+		{
+			VariableSetStmt *sstmt = (VariableSetStmt *) defel->arg;
+			char *value = ExtractSetVariableArgs(sstmt);
+
+			tmp = deparse_FunctionSet(sstmt->kind, sstmt->name, value);
+			sets = lappend(sets, new_object_object(tmp));
+		}
+	}
+	append_array_object(createFunc, "set_options", sets);
 
 	if (probin == NULL)
 	{
@@ -3114,8 +3161,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)
@@ -3203,8 +3248,12 @@ deparse_AlterFunction(Oid objectId, Node *parsetree)
 									 defGetNumeric(defel));
 		}
 		else if (strcmp(defel->defname, "set") == 0)
-			elog(ERROR, "unimplemented deparse of ALTER FUNCTION SET");
+		{
+			VariableSetStmt *sstmt = (VariableSetStmt *) defel->arg;
+			char *value = ExtractSetVariableArgs(sstmt);
 
+			tmp = deparse_FunctionSet(sstmt->kind, sstmt->name, value);
+		}
 		elems = lappend(elems, new_object_object(tmp));
 	}
 
-- 
2.3.0.149.gf3f4077.dirty

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to