From: Alvaro Herrera Date: Fri, 21 Feb 2014 21:11:35 +0000 (-0300) Subject: deparse: Add support for CREATE EXTENSION X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=1d77fe23db14a3adf690f644cf854db8a9748bb5;p=users%2Fandresfreund%2Fpostgres.git deparse: Add support for CREATE EXTENSION --- diff --git a/src/backend/tcop/deparse_utility.c b/src/backend/tcop/deparse_utility.c index f01d912bc7..ffe6326908 100644 --- a/src/backend/tcop/deparse_utility.c +++ b/src/backend/tcop/deparse_utility.c @@ -35,6 +35,7 @@ #include "catalog/pg_collation.h" #include "catalog/pg_constraint.h" #include "catalog/pg_depend.h" +#include "catalog/pg_extension.h" #include "catalog/pg_inherits.h" #include "catalog/pg_operator.h" #include "catalog/pg_opclass.h" @@ -625,6 +626,85 @@ get_persistence_str(char persistence) } } +/* + * deparse_CreateExtensionStmt + * deparse a CreateExtensionStmt + * + * Given an extension OID and the parsetree that created it, return the JSON + * blob representing the creation command. + * + * XXX the current representation makes the output command dependant on the + * installed versions of the extension. Is this a problem? + */ +static char * +deparse_CreateExtensionStmt(Oid objectId, Node *parsetree) +{ + CreateExtensionStmt *node = (CreateExtensionStmt *) parsetree; + Relation pg_extension; + HeapTuple extTup; + Form_pg_extension extForm; + ObjTree *extStmt; + ObjTree *tmp; + char *command; + List *list; + ListCell *cell; + + pg_extension = heap_open(ExtensionRelationId, AccessShareLock); + extTup = get_catalog_object_by_oid(pg_extension, objectId); + if (!HeapTupleIsValid(extTup)) + elog(ERROR, "cache lookup failed for extension with OID %u", + objectId); + extForm = (Form_pg_extension) GETSTRUCT(extTup); + + extStmt = new_objtree_VA("CREATE EXTENSION %{if_not_exists}s %{identity}I " + "%{options: }s", + 1, "identity", ObjTypeString, node->extname); + append_string_object(extStmt, "if_not_exists", + node->if_not_exists ? "IF NOT EXISTS" : ""); + list = NIL; + foreach(cell, node->options) + { + DefElem *opt = (DefElem *) lfirst(cell); + + if (strcmp(opt->defname, "schema") == 0) + { + /* skip this one; we add one unconditionally below */ + continue; + } + else if (strcmp(opt->defname, "new_version") == 0) + { + tmp = new_objtree_VA("VERSION %{version}L", 2, + "type", ObjTypeString, "version", + "version", ObjTypeString, defGetString(opt)); + list = lappend(list, new_object_object(NULL, tmp)); + } + else if (strcmp(opt->defname, "old_version") == 0) + { + tmp = new_objtree_VA("FROM %{version}L", 2, + "type", ObjTypeString, "from", + "version", ObjTypeString, defGetString(opt)); + list = lappend(list, new_object_object(NULL, tmp)); + } + else + elog(ERROR, "unsupported option %s", opt->defname); + } + + tmp = new_objtree_VA("SCHEMA %{schema}I", + 2, "type", ObjTypeString, "schema", + "schema", ObjTypeString, + get_namespace_name(extForm->extnamespace)); + list = lappend(list, new_object_object(NULL, tmp)); + + append_array_object(extStmt, "options", list); + + heap_close(pg_extension, AccessShareLock); + + command = jsonize_objtree(extStmt); + free_objtree(extStmt); + + return command; +} + /* * deparse_ViewStmt * deparse a ViewStmt @@ -2053,10 +2133,13 @@ deparse_parsenode_cmd(StashedCommand *cmd) /* other local objects */ case T_DefineStmt: - case T_CreateExtensionStmt: command = NULL; break; + case T_CreateExtensionStmt: + command = deparse_CreateExtensionStmt(objectId, parsetree); + break; + case T_CompositeTypeStmt: /* CREATE TYPE (composite) */ command = deparse_CompositeTypeStmt(objectId, parsetree); break; diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 0528c78c89..63fba50317 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1178,7 +1178,8 @@ ProcessUtilitySlow(Node *parsetree, case T_AlterExtensionStmt: EventTriggerStashExtensionStart(); - ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree); + objectId = ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree); + EventTriggerStashCommand(objectId, OBJECT_EXTENSION, parsetree); EventTriggerStashExtensionStop(); break;