deparse: Support CREATE EXTENSION
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 21 Feb 2014 21:11:35 +0000 (18:11 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Mon, 13 Oct 2014 03:19:46 +0000 (00:19 -0300)
src/backend/tcop/deparse_utility.c

index 86726372beea5a4660116c38c2c02aafb16ffb7d..3d69653d251cefb6cbc3947b0100af2b017038af 100644 (file)
@@ -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"
@@ -564,6 +565,81 @@ 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 ObjTree *
+deparse_CreateExtensionStmt(Oid objectId, Node *parsetree)
+{
+   CreateExtensionStmt *node = (CreateExtensionStmt *) parsetree;
+   Relation    pg_extension;
+   HeapTuple   extTup;
+   Form_pg_extension extForm;
+   ObjTree    *extStmt;
+   ObjTree    *tmp;
+   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(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(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(tmp));
+
+   append_array_object(extStmt, "options", list);
+
+   heap_close(pg_extension, AccessShareLock);
+
+   return extStmt;
+}
+
 /*
  * deparse_CreateTrigStmt
  *     Deparse a CreateTrigStmt (CREATE TRIGGER)
@@ -1932,7 +2008,7 @@ deparse_simple_command(StashedCommand *cmd)
            break;
 
        case T_CreateExtensionStmt:
-           command = NULL;
+           command = deparse_CreateExtensionStmt(objectId, parsetree);
            break;
 
        case T_AlterExtensionStmt: