deparse: Support ALTER OPERATOR FAMILY
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Sat, 14 Feb 2015 18:43:29 +0000 (15:43 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 7 Apr 2015 17:09:39 +0000 (14:09 -0300)
src/backend/commands/opclasscmds.c
src/backend/tcop/deparse_utility.c

index d5ca502530e4ca9adfa36facfb7751121cbd5203..68624c3269cd26787de97696548dbf54f1907aff 100644 (file)
@@ -36,6 +36,7 @@
 #include "catalog/pg_type.h"
 #include "commands/alter.h"
 #include "commands/defrem.h"
+#include "commands/event_trigger.h"
 #include "miscadmin.h"
 #include "parser/parse_func.h"
 #include "parser/parse_oper.h"
 #include "utils/tqual.h"
 
 
-static void AlterOpFamilyAdd(List *opfamilyname, Oid amoid, Oid opfamilyoid,
+static void AlterOpFamilyAdd(AlterOpFamilyStmt *stmt,
+                List *opfamilyname, Oid amoid, Oid opfamilyoid,
                 int maxOpNumber, int maxProcNumber,
                 List *items);
-static void AlterOpFamilyDrop(List *opfamilyname, Oid amoid, Oid opfamilyoid,
+static void AlterOpFamilyDrop(AlterOpFamilyStmt *stmt,
+                 List *opfamilyname, Oid amoid, Oid opfamilyoid,
                  int maxOpNumber, int maxProcNumber,
                  List *items);
 static void processTypesSpec(List *args, Oid *lefttype, Oid *righttype);
@@ -809,11 +812,11 @@ AlterOpFamily(AlterOpFamilyStmt *stmt)
     * ADD and DROP cases need separate code from here on down.
     */
    if (stmt->isDrop)
-       AlterOpFamilyDrop(stmt->opfamilyname, amoid, opfamilyoid,
+       AlterOpFamilyDrop(stmt, stmt->opfamilyname, amoid, opfamilyoid,
                          maxOpNumber, maxProcNumber,
                          stmt->items);
    else
-       AlterOpFamilyAdd(stmt->opfamilyname, amoid, opfamilyoid,
+       AlterOpFamilyAdd(stmt, stmt->opfamilyname, amoid, opfamilyoid,
                         maxOpNumber, maxProcNumber,
                         stmt->items);
 
@@ -824,7 +827,8 @@ AlterOpFamily(AlterOpFamilyStmt *stmt)
  * ADD part of ALTER OP FAMILY
  */
 static void
-AlterOpFamilyAdd(List *opfamilyname, Oid amoid, Oid opfamilyoid,
+AlterOpFamilyAdd(AlterOpFamilyStmt *stmt,
+                List *opfamilyname, Oid amoid, Oid opfamilyoid,
                 int maxOpNumber, int maxProcNumber,
                 List *items)
 {
@@ -949,13 +953,19 @@ AlterOpFamilyAdd(List *opfamilyname, Oid amoid, Oid opfamilyoid,
                   InvalidOid, operators, true);
    storeProcedures(opfamilyname, amoid, opfamilyoid,
                    InvalidOid, procedures, true);
+
+   /*
+    * make information available to event triggers */
+   EventTriggerStashAlterOpFam(stmt, opfamilyoid,
+                               operators, procedures);
 }
 
 /*
  * DROP part of ALTER OP FAMILY
  */
 static void
-AlterOpFamilyDrop(List *opfamilyname, Oid amoid, Oid opfamilyoid,
+AlterOpFamilyDrop(AlterOpFamilyStmt *stmt,
+                 List *opfamilyname, Oid amoid, Oid opfamilyoid,
                  int maxOpNumber, int maxProcNumber,
                  List *items)
 {
@@ -1022,6 +1032,9 @@ AlterOpFamilyDrop(List *opfamilyname, Oid amoid, Oid opfamilyoid,
     */
    dropOperators(opfamilyname, amoid, opfamilyoid, operators);
    dropProcedures(opfamilyname, amoid, opfamilyoid, procedures);
+
+   EventTriggerStashAlterOpFam(stmt, opfamilyoid,
+                               operators, procedures);
 }
 
 
index 195b06f705659d332f697b18c7deda05b8e253b4..9d083dbc418cdfcecf72ffe3422249d761fca2e7 100644 (file)
@@ -31,6 +31,7 @@
 #include "catalog/heap.h"
 #include "catalog/index.h"
 #include "catalog/namespace.h"
+#include "catalog/opfam_internal.h"
 #include "catalog/pg_aggregate.h"
 #include "catalog/pg_authid.h"
 #include "catalog/pg_cast.h"
@@ -139,9 +140,7 @@ static void append_bool_object(ObjTree *tree, char *name, bool value);
 static void append_string_object(ObjTree *tree, char *name, char *value);
 static void append_object_object(ObjTree *tree, char *name, ObjTree *value);
 static void append_array_object(ObjTree *tree, char *name, List *array);
-#ifdef NOT_USED
 static void append_integer_object(ObjTree *tree, char *name, int64 value);
-#endif
 static void append_float_object(ObjTree *tree, char *name, float8 value);
 static inline void append_premade_object(ObjTree *tree, ObjElem *elem);
 static JsonbValue *objtree_to_jsonb_rec(ObjTree *tree, JsonbParseState *state);
@@ -345,7 +344,6 @@ new_float_object(float8 value)
    return param;
 }
 
-#ifdef NOT_USED
 /*
  * Append an int64 parameter to a tree.
  */
@@ -358,7 +356,6 @@ append_integer_object(ObjTree *tree, char *name, int64 value)
    param->name = name;
    append_premade_object(tree, param);
 }
-#endif
 
 /*
  * Append a float8 parameter to a tree.
@@ -5557,6 +5554,142 @@ deparse_GrantStmt(StashedCommand *cmd)
    return grantStmt;
 }
 
+/*
+ * Deparse an ALTER OPERATOR FAMILY ADD/DROP command.
+ */
+static ObjTree *
+deparse_AlterOpFamily(StashedCommand *cmd)
+{
+   ObjTree    *alterOpFam;
+   AlterOpFamilyStmt *stmt = (AlterOpFamilyStmt *) cmd->parsetree;
+   HeapTuple   ftp;
+   Form_pg_opfamily opfForm;
+   List       *list;
+   ListCell   *cell;
+
+   ftp = SearchSysCache1(OPFAMILYOID,
+                         ObjectIdGetDatum(cmd->d.opfam.opfamOid));
+   if (!HeapTupleIsValid(ftp))
+       elog(ERROR, "cache lookup failed for operator family %u", cmd->d.opfam.opfamOid);
+   opfForm = (Form_pg_opfamily) GETSTRUCT(ftp);
+
+   if (!stmt->isDrop)
+       alterOpFam = new_objtree_VA("ALTER OPERATOR FAMILY %{identity}D "
+                                   "USING %{amname}I ADD %{items:, }s", 0);
+   else
+       alterOpFam = new_objtree_VA("ALTER OPERATOR FAMILY %{identity}D "
+                                   "USING %{amname}I DROP %{items:, }s", 0);
+   append_object_object(alterOpFam, "identity",
+                        new_objtree_for_qualname(opfForm->opfnamespace,
+                                                 NameStr(opfForm->opfname)));
+   append_string_object(alterOpFam, "amname", stmt->amname);
+
+   list = NIL;
+   foreach(cell, cmd->d.opfam.operators)
+   {
+       OpFamilyMember *oper = lfirst(cell);
+       ObjTree    *tmp;
+
+       if (!stmt->isDrop)
+           tmp = new_objtree_VA("OPERATOR %{num}n %{operator}O(%{ltype}T, %{rtype}T) %{purpose}s",
+                                0);
+       else
+           tmp = new_objtree_VA("OPERATOR %{num}n (%{ltype}T, %{rtype}T)",
+                                0);
+       append_integer_object(tmp, "num", oper->number);
+
+       /* Add the operator name; the DROP case doesn't have this */
+       if (!stmt->isDrop)
+       {
+           append_object_object(tmp, "operator",
+                                new_objtree_for_qualname_id(OperatorRelationId,
+                                                            oper->object));
+       }
+
+       /* Add the types */
+       append_object_object(tmp, "ltype",
+                            new_objtree_for_type(oper->lefttype, -1));
+       append_object_object(tmp, "rtype",
+                            new_objtree_for_type(oper->righttype, -1));
+
+       /* Add the FOR SEARCH / FOR ORDER BY clause; not in the DROP case */
+       if (!stmt->isDrop)
+       {
+           if (oper->sortfamily == InvalidOid)
+               append_string_object(tmp, "purpose", "FOR SEARCH");
+           else
+           {
+               ObjTree    *tmp2;
+
+               tmp2 = new_objtree_VA("FOR ORDER BY %{opfamily}D", 0);
+               append_object_object(tmp2, "opfamily",
+                                    new_objtree_for_qualname_id(OperatorFamilyRelationId,
+                                                                oper->sortfamily));
+               append_object_object(tmp, "purpose", tmp2);
+           }
+       }
+
+       list = lappend(list, new_object_object(tmp));
+   }
+
+   foreach(cell, cmd->d.opfam.procedures)
+   {
+       OpFamilyMember *proc = lfirst(cell);
+       ObjTree    *tmp;
+
+       if (!stmt->isDrop)
+           tmp = new_objtree_VA("FUNCTION %{num}n (%{ltype}T, %{rtype}T) %{function}D(%{argtypes:, }T)", 0);
+       else
+           tmp = new_objtree_VA("FUNCTION %{num}n (%{ltype}T, %{rtype}T)", 0);
+       append_integer_object(tmp, "num", proc->number);
+
+       /* Add the function name and arg types; the DROP case doesn't have this */
+       if (!stmt->isDrop)
+       {
+           HeapTuple   procTup;
+           Form_pg_proc procForm;
+           Oid        *proargtypes;
+           List       *arglist;
+           int         i;
+
+           procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(proc->object));
+           if (!HeapTupleIsValid(procTup))
+               elog(ERROR, "cache lookup failed for procedure %u", proc->object);
+           procForm = (Form_pg_proc) GETSTRUCT(procTup);
+
+           append_object_object(tmp, "function",
+                                new_objtree_for_qualname(procForm->pronamespace,
+                                                         NameStr(procForm->proname)));
+           proargtypes = procForm->proargtypes.values;
+           arglist = NIL;
+           for (i = 0; i < procForm->pronargs; i++)
+           {
+               ObjTree    *arg;
+
+               arg = new_objtree_for_type(proargtypes[i], -1);
+               arglist = lappend(arglist, new_object_object(arg));
+           }
+           append_array_object(tmp, "argtypes", arglist);
+
+           ReleaseSysCache(procTup);
+       }
+
+       /* Add the types */
+       append_object_object(tmp, "ltype",
+                            new_objtree_for_type(proc->lefttype, -1));
+       append_object_object(tmp, "rtype",
+                            new_objtree_for_type(proc->righttype, -1));
+
+       list = lappend(list, new_object_object(tmp));
+   }
+
+   append_array_object(alterOpFam, "items", list);
+
+   ReleaseSysCache(ftp);
+
+   return alterOpFam;
+}
+
 static ObjTree *
 deparse_AlterTableStmt(StashedCommand *cmd)
 {