Add system catalog columns pg_constraint.conindid and pg_trigger.tgconstrindid.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 28 Jul 2009 02:56:31 +0000 (02:56 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 28 Jul 2009 02:56:31 +0000 (02:56 +0000)
conindid is the index supporting a constraint.  We can use this not only for
unique/primary-key constraints, but also foreign-key constraints, which
depend on the unique index that constrains the referenced columns.
tgconstrindid is just copied from the constraint's conindid field, or is
zero for triggers not associated with constraints.

This is mainly intended as infrastructure for upcoming patches, but it has
some virtue in itself, since it exposes a relationship that you formerly
had to grovel in pg_depend to determine.  I simplified one information_schema
view accordingly.  (There is a pg_dump query that could also use conindid,
but I left it alone because it wasn't clear it'd get any faster.)

15 files changed:
doc/src/sgml/catalogs.sgml
doc/src/sgml/trigger.sgml
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/catalog/information_schema.sql
src/backend/catalog/pg_constraint.c
src/backend/commands/tablecmds.c
src/backend/commands/trigger.c
src/backend/commands/typecmds.c
src/backend/tcop/utility.c
src/include/catalog/catversion.h
src/include/catalog/pg_constraint.h
src/include/catalog/pg_trigger.h
src/include/commands/trigger.h
src/include/utils/rel.h

index 34679d85ea5238598165dafb99ef27c2338ae252..46a770469a5e98377e75c4d6b22063832b3ba834 100644 (file)
       <entry>The domain this constraint is on; 0 if not a domain constraint</entry>
      </row>
 
+     <row>
+      <entry><structfield>conindid</structfield></entry>
+      <entry><type>oid</type></entry>
+      <entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
+      <entry>The index supporting this constraint, if it's a unique, primary
+       key, or foreign key constraint; else 0</entry>
+     </row>
+
      <row>
       <entry><structfield>confrelid</structfield></entry>
       <entry><type>oid</type></entry>
       <entry>The table referenced by a referential integrity constraint</entry>
      </row>
 
+     <row>
+      <entry><structfield>tgconstrindid</structfield></entry>
+      <entry><type>oid</type></entry>
+      <entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
+      <entry>The index supporting a unique, primary key, or referential integrity constraint</entry>
+     </row>
+
      <row>
       <entry><structfield>tgconstraint</structfield></entry>
       <entry><type>oid</type></entry>
     When <structfield>tgconstraint</> is nonzero,
     <structfield>tgisconstraint</> must be true, and
     <structfield>tgconstrname</>, <structfield>tgconstrrelid</>,
+    <structfield>tgconstrindid</>,
     <structfield>tgdeferrable</>, <structfield>tginitdeferred</> are redundant
     with the referenced <structname>pg_constraint</> entry.  The reason we
     keep these fields is that we support <quote>stand-alone</> constraint
index 9ee2f94d8a33d6d11b42896df65a23c3b96d85cc..2cb4e05d5d439cc9bd48737e7926ed02ad6de555 100644 (file)
@@ -486,6 +486,7 @@ typedef struct Trigger
     bool        tgenabled;
     bool        tgisconstraint;
     Oid         tgconstrrelid;
+    Oid         tgconstrindid;
     Oid         tgconstraint;
     bool        tgdeferrable;
     bool        tginitdeferred;
@@ -497,7 +498,7 @@ typedef struct Trigger
 </programlisting>
 
        where <structfield>tgname</> is the trigger's name,
-       <structfield>tgnargs</> is number of arguments in
+       <structfield>tgnargs</> is the number of arguments in
        <structfield>tgargs</>, and <structfield>tgargs</> is an array of
        pointers to the arguments specified in the <command>CREATE
        TRIGGER</command> statement. The other members are for internal use
index 7557400680fed6129f2560e01f2d6b1e8bb638ae..fbb9c5c6d7d10b87186becc4c48f89b561a8d041 100644 (file)
@@ -1659,6 +1659,7 @@ StoreRelCheck(Relation rel, char *ccname, Node *expr,
                                                  attNos,               /* attrs in the constraint */
                                                  keycount,             /* # attrs in the constraint */
                                                  InvalidOid,   /* not a domain constraint */
+                                                 InvalidOid,   /* no associated index */
                                                  InvalidOid,   /* Foreign key fields */
                                                  NULL,
                                                  NULL,
@@ -1668,7 +1669,6 @@ StoreRelCheck(Relation rel, char *ccname, Node *expr,
                                                  ' ',
                                                  ' ',
                                                  ' ',
-                                                 InvalidOid,   /* no associated index */
                                                  expr, /* Tree form check constraint */
                                                  ccbin,        /* Binary form check constraint */
                                                  ccsrc,        /* Source form check constraint */
index c4e4cabda94c6cca058852d4411e9efcea3f1af0..4febd8eec0e58be92010e71d482184b2f311e420 100644 (file)
@@ -732,6 +732,7 @@ index_create(Oid heapRelationId,
                                                                                   indexInfo->ii_KeyAttrNumbers,
                                                                                   indexInfo->ii_NumIndexAttrs,
                                                                                   InvalidOid,  /* no domain */
+                                                                                  indexRelationId,     /* index OID */
                                                                                   InvalidOid,  /* no foreign key */
                                                                                   NULL,
                                                                                   NULL,
@@ -741,7 +742,6 @@ index_create(Oid heapRelationId,
                                                                                   ' ',
                                                                                   ' ',
                                                                                   ' ',
-                                                                                  InvalidOid,  /* no associated index */
                                                                                   NULL,                /* no check constraint */
                                                                                   NULL,
                                                                                   NULL,
index 0f8d3c737c8effb72003e95958814748815dea85..637683257d3fae60a1651693a855c925cd56d96b 100644 (file)
@@ -44,17 +44,6 @@ CREATE FUNCTION _pg_keysequal(smallint[], smallint[]) RETURNS boolean
     LANGUAGE sql IMMUTABLE  -- intentionally not STRICT, to allow inlining
     AS 'select $1 <@ $2 and $2 <@ $1';
 
-/* Get the OID of the unique index that an FK constraint depends on */
-CREATE FUNCTION _pg_underlying_index(oid) RETURNS oid
-    LANGUAGE sql STRICT STABLE
-    AS $$
-SELECT refobjid FROM pg_catalog.pg_depend
-  WHERE classid = 'pg_catalog.pg_constraint'::pg_catalog.regclass AND
-        objid = $1 AND
-        refclassid = 'pg_catalog.pg_class'::pg_catalog.regclass AND
-        refobjsubid = 0 AND deptype = 'n'
-$$;
-
 /* Given an index's OID and an underlying-table column number, return the
  * column's position in the index (NULL if not there) */
 CREATE FUNCTION _pg_index_position(oid, smallint) RETURNS int
@@ -957,15 +946,15 @@ CREATE VIEW key_column_usage AS
            CAST(a.attname AS sql_identifier) AS column_name,
            CAST((ss.x).n AS cardinal_number) AS ordinal_position,
            CAST(CASE WHEN contype = 'f' THEN
-                  _pg_index_position(_pg_underlying_index(ss.coid),
-                                     ss.confkey[(ss.x).n])
+                       _pg_index_position(ss.conindid, ss.confkey[(ss.x).n])
                      ELSE NULL
                 END AS cardinal_number)
              AS position_in_unique_constraint
     FROM pg_attribute a,
          (SELECT r.oid AS roid, r.relname, r.relowner,
                  nc.nspname AS nc_nspname, nr.nspname AS nr_nspname,
-                 c.oid AS coid, c.conname, c.contype, c.confkey, c.confrelid,
+                 c.oid AS coid, c.conname, c.contype, c.conindid,
+                 c.confkey, c.confrelid,
                  _pg_expandarray(c.conkey) AS x
           FROM pg_namespace nr, pg_class r, pg_namespace nc,
                pg_constraint c
index 6b6dcd38710a38288e1cc1170d185e836dbfd3a4..4ad48ce2324f74fa78883145daf1ad05f81980ac 100644 (file)
@@ -49,6 +49,7 @@ CreateConstraintEntry(const char *constraintName,
                                          const int16 *constraintKey,
                                          int constraintNKeys,
                                          Oid domainId,
+                                         Oid indexRelId,
                                          Oid foreignRelId,
                                          const int16 *foreignKey,
                                          const Oid *pfEqOp,
@@ -58,7 +59,6 @@ CreateConstraintEntry(const char *constraintName,
                                          char foreignUpdateType,
                                          char foreignDeleteType,
                                          char foreignMatchType,
-                                         Oid indexRelId,
                                          Node *conExpr,
                                          const char *conBin,
                                          const char *conSrc,
@@ -144,6 +144,7 @@ CreateConstraintEntry(const char *constraintName,
        values[Anum_pg_constraint_condeferred - 1] = BoolGetDatum(isDeferred);
        values[Anum_pg_constraint_conrelid - 1] = ObjectIdGetDatum(relId);
        values[Anum_pg_constraint_contypid - 1] = ObjectIdGetDatum(domainId);
+       values[Anum_pg_constraint_conindid - 1] = ObjectIdGetDatum(indexRelId);
        values[Anum_pg_constraint_confrelid - 1] = ObjectIdGetDatum(foreignRelId);
        values[Anum_pg_constraint_confupdtype - 1] = CharGetDatum(foreignUpdateType);
        values[Anum_pg_constraint_confdeltype - 1] = CharGetDatum(foreignDeleteType);
@@ -273,11 +274,13 @@ CreateConstraintEntry(const char *constraintName,
                }
        }
 
-       if (OidIsValid(indexRelId))
+       if (OidIsValid(indexRelId) && constraintType == CONSTRAINT_FOREIGN)
        {
                /*
                 * Register normal dependency on the unique index that supports a
-                * foreign-key constraint.
+                * foreign-key constraint.  (Note: for indexes associated with
+                * unique or primary-key constraints, the dependency runs the other
+                * way, and is not made here.)
                 */
                ObjectAddress relobject;
 
index b0a633c5056dbe63dcb8e33cacd41266acf394d4..97f3b3c4438e7b7299eae31e154cb71ab5cd645c 100644 (file)
@@ -152,6 +152,7 @@ typedef struct NewConstraint
        char       *name;                       /* Constraint name, or NULL if none */
        ConstrType      contype;                /* CHECK or FOREIGN */
        Oid                     refrelid;               /* PK rel, if FOREIGN */
+       Oid                     refindid;               /* OID of PK's index, if FOREIGN */
        Oid                     conid;                  /* OID of pg_constraint entry, if FOREIGN */
        Node       *qual;                       /* Check expr or FkConstraint struct */
        List       *qualstate;          /* Execution state for CHECK */
@@ -247,9 +248,10 @@ static Oid transformFkeyCheckAttrs(Relation pkrel,
                                                Oid *opclasses);
 static void checkFkeyPermissions(Relation rel, int16 *attnums, int natts);
 static void validateForeignKeyConstraint(FkConstraint *fkconstraint,
-                                                        Relation rel, Relation pkrel, Oid constraintOid);
+                                                        Relation rel, Relation pkrel,
+                                                        Oid pkindOid, Oid constraintOid);
 static void createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
-                                                Oid constraintOid);
+                                                Oid constraintOid, Oid indexOid);
 static void ATController(Relation rel, List *cmds, bool recurse);
 static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                  bool recurse, bool recursing);
@@ -2915,6 +2917,7 @@ ATRewriteTables(List **wqueue)
                                refrel = heap_open(con->refrelid, RowShareLock);
 
                                validateForeignKeyConstraint(fkconstraint, rel, refrel,
+                                                                                        con->refindid,
                                                                                         con->conid);
 
                                heap_close(refrel, NoLock);
@@ -4819,6 +4822,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
                                                                          numfks,
                                                                          InvalidOid,           /* not a domain
                                                                                                                 * constraint */
+                                                                         indexOid,
                                                                          RelationGetRelid(pkrel),
                                                                          pkattnum,
                                                                          pfeqoperators,
@@ -4828,7 +4832,6 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
                                                                          fkconstraint->fk_upd_action,
                                                                          fkconstraint->fk_del_action,
                                                                          fkconstraint->fk_matchtype,
-                                                                         indexOid,
                                                                          NULL,         /* no check constraint */
                                                                          NULL,
                                                                          NULL,
@@ -4838,7 +4841,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
        /*
         * Create the triggers that will enforce the constraint.
         */
-       createForeignKeyTriggers(rel, fkconstraint, constrOid);
+       createForeignKeyTriggers(rel, fkconstraint, constrOid, indexOid);
 
        /*
         * Tell Phase 3 to check that the constraint is satisfied by existing rows
@@ -4852,6 +4855,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
                newcon->name = fkconstraint->constr_name;
                newcon->contype = CONSTR_FOREIGN;
                newcon->refrelid = RelationGetRelid(pkrel);
+               newcon->refindid = indexOid;
                newcon->conid = constrOid;
                newcon->qual = (Node *) fkconstraint;
 
@@ -5141,6 +5145,7 @@ static void
 validateForeignKeyConstraint(FkConstraint *fkconstraint,
                                                         Relation rel,
                                                         Relation pkrel,
+                                                        Oid pkindOid,
                                                         Oid constraintOid)
 {
        HeapScanDesc scan;
@@ -5156,6 +5161,7 @@ validateForeignKeyConstraint(FkConstraint *fkconstraint,
        trig.tgenabled = TRIGGER_FIRES_ON_ORIGIN;
        trig.tgisconstraint = TRUE;
        trig.tgconstrrelid = RelationGetRelid(pkrel);
+       trig.tgconstrindid = pkindOid;
        trig.tgconstraint = constraintOid;
        trig.tgdeferrable = FALSE;
        trig.tginitdeferred = FALSE;
@@ -5209,7 +5215,7 @@ validateForeignKeyConstraint(FkConstraint *fkconstraint,
 
 static void
 CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint,
-                                        Oid constraintOid, bool on_insert)
+                                        Oid constraintOid, Oid indexOid, bool on_insert)
 {
        CreateTrigStmt *fk_trigger;
 
@@ -5237,7 +5243,7 @@ CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint,
        fk_trigger->constrrel = fkconstraint->pktable;
        fk_trigger->args = NIL;
 
-       (void) CreateTrigger(fk_trigger, constraintOid, false);
+       (void) CreateTrigger(fk_trigger, constraintOid, indexOid, false);
 
        /* Make changes-so-far visible */
        CommandCounterIncrement();
@@ -5248,7 +5254,7 @@ CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint,
  */
 static void
 createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
-                                                Oid constraintOid)
+                                                Oid constraintOid, Oid indexOid)
 {
        RangeVar   *myRel;
        CreateTrigStmt *fk_trigger;
@@ -5267,8 +5273,8 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
         * Build and execute a CREATE CONSTRAINT TRIGGER statement for the CHECK
         * action for both INSERTs and UPDATEs on the referencing table.
         */
-       CreateFKCheckTrigger(myRel, fkconstraint, constraintOid, true);
-       CreateFKCheckTrigger(myRel, fkconstraint, constraintOid, false);
+       CreateFKCheckTrigger(myRel, fkconstraint, constraintOid, indexOid, true);
+       CreateFKCheckTrigger(myRel, fkconstraint, constraintOid, indexOid, false);
 
        /*
         * Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
@@ -5316,7 +5322,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
        }
        fk_trigger->args = NIL;
 
-       (void) CreateTrigger(fk_trigger, constraintOid, false);
+       (void) CreateTrigger(fk_trigger, constraintOid, indexOid, false);
 
        /* Make changes-so-far visible */
        CommandCounterIncrement();
@@ -5367,7 +5373,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
        }
        fk_trigger->args = NIL;
 
-       (void) CreateTrigger(fk_trigger, constraintOid, false);
+       (void) CreateTrigger(fk_trigger, constraintOid, indexOid, false);
 }
 
 /*
index bd46102bb287fd7681058dff04afd6cd34aec6bc..d1431af464408a2c8e0ad56b52a96fcd6dfabd79 100644 (file)
@@ -74,6 +74,9 @@ static void AfterTriggerSaveEvent(ResultRelInfo *relinfo, int event,
  * be made to link the trigger to that constraint.     constraintOid is zero when
  * executing a user-entered CREATE TRIGGER command.
  *
+ * indexOid, if nonzero, is the OID of an index associated with the constraint.
+ * We do nothing with this except store it into pg_trigger.tgconstrindid.
+ *
  * If checkPermissions is true we require ACL_TRIGGER permissions on the
  * relation.  If not, the caller already checked permissions.  (This is
  * currently redundant with constraintOid being zero, but it's clearer to
@@ -83,7 +86,9 @@ static void AfterTriggerSaveEvent(ResultRelInfo *relinfo, int event,
  * but a foreign-key constraint.  This is a kluge for backwards compatibility.
  */
 Oid
-CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid, bool checkPermissions)
+CreateTrigger(CreateTrigStmt *stmt,
+                         Oid constraintOid, Oid indexOid,
+                         bool checkPermissions)
 {
        int16           tgtype;
        int2vector *tgattr;
@@ -276,6 +281,7 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid, bool checkPermissions)
        values[Anum_pg_trigger_tgconstrname - 1] = DirectFunctionCall1(namein,
                                                                                                CStringGetDatum(constrname));
        values[Anum_pg_trigger_tgconstrrelid - 1] = ObjectIdGetDatum(constrrelid);
+       values[Anum_pg_trigger_tgconstrindid - 1] = ObjectIdGetDatum(indexOid);
        values[Anum_pg_trigger_tgconstraint - 1] = ObjectIdGetDatum(constraintOid);
        values[Anum_pg_trigger_tgdeferrable - 1] = BoolGetDatum(stmt->deferrable);
        values[Anum_pg_trigger_tginitdeferred - 1] = BoolGetDatum(stmt->initdeferred);
@@ -410,13 +416,15 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid, bool checkPermissions)
                referenced.objectId = RelationGetRelid(rel);
                referenced.objectSubId = 0;
                recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
-               if (constrrelid != InvalidOid)
+               if (OidIsValid(constrrelid))
                {
                        referenced.classId = RelationRelationId;
                        referenced.objectId = constrrelid;
                        referenced.objectSubId = 0;
                        recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
                }
+               /* Not possible to have an index dependency in this case */
+               Assert(!OidIsValid(indexOid));
        }
 
        /* Keep lock on target rel until end of xact */
@@ -1122,6 +1130,7 @@ RelationBuildTriggers(Relation relation)
                build->tgenabled = pg_trigger->tgenabled;
                build->tgisconstraint = pg_trigger->tgisconstraint;
                build->tgconstrrelid = pg_trigger->tgconstrrelid;
+               build->tgconstrindid = pg_trigger->tgconstrindid;
                build->tgconstraint = pg_trigger->tgconstraint;
                build->tgdeferrable = pg_trigger->tgdeferrable;
                build->tginitdeferred = pg_trigger->tginitdeferred;
@@ -1467,6 +1476,8 @@ equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
                                return false;
                        if (trig1->tgconstrrelid != trig2->tgconstrrelid)
                                return false;
+                       if (trig1->tgconstrindid != trig2->tgconstrindid)
+                               return false;
                        if (trig1->tgconstraint != trig2->tgconstraint)
                                return false;
                        if (trig1->tgdeferrable != trig2->tgdeferrable)
index 5a18b3033f8f40ac3ef0688519b5fe1f11e86c94..06e9b906125dcd6e1d626b61e26ed1f46ea600c7 100644 (file)
@@ -2293,6 +2293,7 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
                                                  NULL,
                                                  0,
                                                  domainOid,    /* domain constraint */
+                                                 InvalidOid,   /* no associated index */
                                                  InvalidOid,   /* Foreign key fields */
                                                  NULL,
                                                  NULL,
@@ -2302,7 +2303,6 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
                                                  ' ',
                                                  ' ',
                                                  ' ',
-                                                 InvalidOid,
                                                  expr, /* Tree form check constraint */
                                                  ccbin,        /* Binary form check constraint */
                                                  ccsrc,        /* Source form check constraint */
index 04d6c4c8d72cccfc55447ccf8183284c5150461d..f043b88382d379cd71a639e0f14c7b080cf1e8ad 100644 (file)
@@ -928,7 +928,8 @@ ProcessUtility(Node *parsetree,
                        break;
 
                case T_CreateTrigStmt:
-                       CreateTrigger((CreateTrigStmt *) parsetree, InvalidOid, true);
+                       CreateTrigger((CreateTrigStmt *) parsetree,
+                                                 InvalidOid, InvalidOid, true);
                        break;
 
                case T_DropPropertyStmt:
index 98eba9b69969458f604f8a2c6d2462bf85f88e57..bb4483865b669a917b032f1e53b58ab8d9218150 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200907071
+#define CATALOG_VERSION_NO     200907271
 
 #endif
index d8e4733e914e262ef938f876f07226782427eb83..fa70c140e9c2a2763cdd059e23356de1b4405881 100644 (file)
@@ -62,6 +62,16 @@ CATALOG(pg_constraint,2606)
         */
        Oid                     contypid;               /* domain this constraint constrains */
 
+       /*
+        * conindid links to the index supporting the constraint, if any;
+        * otherwise it's 0.  This is used for unique and primary-key constraints,
+        * and less obviously for foreign-key constraints (where the index is
+        * a unique index on the referenced relation's referenced columns).
+        * Notice that the index is on conrelid in the first case but confrelid
+        * in the second.
+        */
+       Oid                     conindid;               /* index supporting this constraint */
+
        /*
         * These fields, plus confkey, are only meaningful for a foreign-key
         * constraint.  Otherwise confrelid is 0 and the char fields are spaces.
@@ -131,7 +141,7 @@ typedef FormData_pg_constraint *Form_pg_constraint;
  *             compiler constants for pg_constraint
  * ----------------
  */
-#define Natts_pg_constraint                                    20
+#define Natts_pg_constraint                                    21
 #define Anum_pg_constraint_conname                     1
 #define Anum_pg_constraint_connamespace                2
 #define Anum_pg_constraint_contype                     3
@@ -139,19 +149,20 @@ typedef FormData_pg_constraint *Form_pg_constraint;
 #define Anum_pg_constraint_condeferred         5
 #define Anum_pg_constraint_conrelid                    6
 #define Anum_pg_constraint_contypid                    7
-#define Anum_pg_constraint_confrelid           8
-#define Anum_pg_constraint_confupdtype         9
-#define Anum_pg_constraint_confdeltype         10
-#define Anum_pg_constraint_confmatchtype       11
-#define Anum_pg_constraint_conislocal          12
-#define Anum_pg_constraint_coninhcount         13
-#define Anum_pg_constraint_conkey                      14
-#define Anum_pg_constraint_confkey                     15
-#define Anum_pg_constraint_conpfeqop           16
-#define Anum_pg_constraint_conppeqop           17
-#define Anum_pg_constraint_conffeqop           18
-#define Anum_pg_constraint_conbin                      19
-#define Anum_pg_constraint_consrc                      20
+#define Anum_pg_constraint_conindid                    8
+#define Anum_pg_constraint_confrelid           9
+#define Anum_pg_constraint_confupdtype         10
+#define Anum_pg_constraint_confdeltype         11
+#define Anum_pg_constraint_confmatchtype       12
+#define Anum_pg_constraint_conislocal          13
+#define Anum_pg_constraint_coninhcount         14
+#define Anum_pg_constraint_conkey                      15
+#define Anum_pg_constraint_confkey                     16
+#define Anum_pg_constraint_conpfeqop           17
+#define Anum_pg_constraint_conppeqop           18
+#define Anum_pg_constraint_conffeqop           19
+#define Anum_pg_constraint_conbin                      20
+#define Anum_pg_constraint_consrc                      21
 
 
 /* Valid values for contype */
@@ -188,6 +199,7 @@ extern Oid CreateConstraintEntry(const char *constraintName,
                                          const int16 *constraintKey,
                                          int constraintNKeys,
                                          Oid domainId,
+                                         Oid indexRelId,
                                          Oid foreignRelId,
                                          const int16 *foreignKey,
                                          const Oid *pfEqOp,
@@ -197,7 +209,6 @@ extern Oid CreateConstraintEntry(const char *constraintName,
                                          char foreignUpdateType,
                                          char foreignDeleteType,
                                          char foreignMatchType,
-                                         Oid indexRelId,
                                          Node *conExpr,
                                          const char *conBin,
                                          const char *conSrc,
index c8b57a1070bf77974d72df54e02bd1a63f687c1e..64ca26fbd35101433221f3eefe307b0fb63ddc96 100644 (file)
  *             typedef struct FormData_pg_trigger
  *
  * Note: when tgconstraint is nonzero, tgisconstraint must be true, and
- * tgconstrname, tgconstrrelid, tgdeferrable, tginitdeferred are redundant
- * with the referenced pg_constraint entry.  The reason we keep these fields
- * is that we support "stand-alone" constraint triggers with no corresponding
- * pg_constraint entry.
+ * tgconstrname, tgconstrrelid, tgconstrindid, tgdeferrable, tginitdeferred
+ * are redundant with the referenced pg_constraint entry.  The reason we keep
+ * these fields is that we support "stand-alone" constraint triggers with no
+ * corresponding pg_constraint entry.
  * ----------------
  */
 #define TriggerRelationId  2620
@@ -46,6 +46,7 @@ CATALOG(pg_trigger,2620)
        bool            tgisconstraint; /* trigger is a constraint trigger */
        NameData        tgconstrname;   /* constraint name */
        Oid                     tgconstrrelid;  /* constraint's FROM table, if any */
+       Oid                     tgconstrindid;  /* constraint's supporting index, if any */
        Oid                     tgconstraint;   /* owning pg_constraint entry, if any */
        bool            tgdeferrable;   /* constraint trigger is deferrable */
        bool            tginitdeferred; /* constraint trigger is deferred initially */
@@ -67,7 +68,7 @@ typedef FormData_pg_trigger *Form_pg_trigger;
  *             compiler constants for pg_trigger
  * ----------------
  */
-#define Natts_pg_trigger                               14
+#define Natts_pg_trigger                               15
 #define Anum_pg_trigger_tgrelid                        1
 #define Anum_pg_trigger_tgname                 2
 #define Anum_pg_trigger_tgfoid                 3
@@ -76,12 +77,13 @@ typedef FormData_pg_trigger *Form_pg_trigger;
 #define Anum_pg_trigger_tgisconstraint 6
 #define Anum_pg_trigger_tgconstrname   7
 #define Anum_pg_trigger_tgconstrrelid  8
-#define Anum_pg_trigger_tgconstraint   9
-#define Anum_pg_trigger_tgdeferrable   10
-#define Anum_pg_trigger_tginitdeferred 11
-#define Anum_pg_trigger_tgnargs                        12
-#define Anum_pg_trigger_tgattr                 13
-#define Anum_pg_trigger_tgargs                 14
+#define Anum_pg_trigger_tgconstrindid  9
+#define Anum_pg_trigger_tgconstraint   10
+#define Anum_pg_trigger_tgdeferrable   11
+#define Anum_pg_trigger_tginitdeferred 12
+#define Anum_pg_trigger_tgnargs                        13
+#define Anum_pg_trigger_tgattr                 14
+#define Anum_pg_trigger_tgargs                 15
 
 /* Bits within tgtype */
 #define TRIGGER_TYPE_ROW                               (1 << 0)
index 7dad6b4c816a17f25e5c7fd47cacbbe2ea0b4411..2383273a1afc727b7addbbad71827729b080ac11 100644 (file)
@@ -104,7 +104,8 @@ extern PGDLLIMPORT int SessionReplicationRole;
 #define TRIGGER_FIRES_ON_REPLICA                       'R'
 #define TRIGGER_DISABLED                                       'D'
 
-extern Oid CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid,
+extern Oid CreateTrigger(CreateTrigStmt *stmt,
+                         Oid constraintOid, Oid indexOid,
                          bool checkPermissions);
 
 extern void DropTrigger(Oid relid, const char *trigname,
index 97ac63772aa1181afd5e1ac681231690afda27f2..146cee745172333ed9c99180e41d91baba232243 100644 (file)
@@ -58,6 +58,7 @@ typedef struct Trigger
        char            tgenabled;
        bool            tgisconstraint;
        Oid                     tgconstrrelid;
+       Oid                     tgconstrindid;
        Oid                     tgconstraint;
        bool            tgdeferrable;
        bool            tginitdeferred;