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