diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index a5b327d942e56d0d8bde57272d4cd7eb7d921bdd..a70c11aa8899d6408706b7682ce8f90703f0ddcc 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.201 2009/07/01 23:57:33 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.202 2009/07/28 02:56:29 tgl Exp $ -->
 <!--
  Documentation of the system catalogs, directed toward PostgreSQL developers
  -->
@@ -1748,6 +1748,14 @@
       <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>
@@ -4510,6 +4518,13 @@
       <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>
@@ -4560,6 +4575,7 @@
     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
diff --git a/doc/src/sgml/trigger.sgml b/doc/src/sgml/trigger.sgml
index 473e107c84012f937b701d4d65ccb0757bd0c885..348434f9174dfc42be44a4cb5e99c3984e7768df 100644
--- a/doc/src/sgml/trigger.sgml
+++ b/doc/src/sgml/trigger.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.56 2009/05/27 01:18:06 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.57 2009/07/28 02:56:29 tgl Exp $ -->
 
  <chapter id="triggers">
   <title>Triggers</title>
@@ -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
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index f4cf829b468100352e6b8c167dbda66a34bc8cee..588c26ad125dd87c660cced8413e5439eb4b5538 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.354 2009/06/11 14:48:54 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.355 2009/07/28 02:56:29 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -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 */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index b75aac04e172d02f8a86b266f61001d8d41a8c7e..0199ca673037971ddd5241d05bb3c92f8813a525 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.318 2009/06/11 14:48:55 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.319 2009/07/28 02:56:29 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -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,
diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql
index cea4f7977571298147f8a0368783ea69eba132c6..36f5b62b4e024d80047d068f94733334ddfb2271 100644
--- a/src/backend/catalog/information_schema.sql
+++ b/src/backend/catalog/information_schema.sql
@@ -4,7 +4,7 @@
  *
  * Copyright (c) 2003-2009, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.57 2009/07/13 20:25:57 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.58 2009/07/28 02:56:29 tgl Exp $
  */
 
 /*
@@ -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
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index e6756b7477c9befb37a4ae3a9b8fd1ed61401953..81c35100c7b286463081f670d47175a8e040fe11 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/pg_constraint.c,v 1.46 2009/07/16 06:33:42 petere Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/pg_constraint.c,v 1.47 2009/07/28 02:56:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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;
 
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 20253e1523fcb35a4b13577e1b834944d32cf27f..e883e8ed91fd4800a8b98fe24d81ebfd19c9f05f 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.291 2009/07/20 02:42:27 adunstan Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.292 2009/07/28 02:56:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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);
 }
 
 /*
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index bb628ed80a3a9b1edbb5c1233a02cf178820ee49..0cc33aae6b60ab463507b53cd36b6a7599fac765 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.248 2009/06/18 01:27:02 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.249 2009/07/28 02:56:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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)
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 659b591423936306460bf3649f9fe2e010f978a0..1d3077cc32400a95db15ae12a0da00ed85b35df0 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.135 2009/07/16 06:33:42 petere Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.136 2009/07/28 02:56:30 tgl Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -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 */
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index e3677c51d61d01462d6f7cb7c5e429017eab4578..126a079f3e473573cd70dbc3fccfd26fd5899fdc 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.311 2009/07/26 23:34:18 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.312 2009/07/28 02:56:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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:
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index ef7f39278797068b3e90de9ee6f5d0ba020a3014..ecbf1056063d518e6b3950f6ac420d58344824f5 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.532 2009/07/07 18:23:14 petere Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.533 2009/07/28 02:56:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	200907071
+#define CATALOG_VERSION_NO	200907271
 
 #endif
diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h
index 24454ef56878448fae9489ebc6e1923d14eb974b..08305e68b655a24c3f971bb299bf5e5c9c1458d5 100644
--- a/src/include/catalog/pg_constraint.h
+++ b/src/include/catalog/pg_constraint.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_constraint.h,v 1.31 2009/07/16 06:33:45 petere Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_constraint.h,v 1.32 2009/07/28 02:56:31 tgl Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -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,
diff --git a/src/include/catalog/pg_trigger.h b/src/include/catalog/pg_trigger.h
index 2f4274107feba03f6a6d6aba616e9cc9cae6f6ed..64730bc60f1a58bf12a3e151fc62c31d1e4e5721 100644
--- a/src/include/catalog/pg_trigger.h
+++ b/src/include/catalog/pg_trigger.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_trigger.h,v 1.33 2009/01/01 17:23:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_trigger.h,v 1.34 2009/07/28 02:56:31 tgl Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -26,10 +26,10 @@
  *		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)
diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h
index 7e886eede41a0fa02576194e2dafe786c04c7972..3e14bbe3baa12b2f770ff3e70394625bd20b7075 100644
--- a/src/include/commands/trigger.h
+++ b/src/include/commands/trigger.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/trigger.h,v 1.73 2009/06/11 14:49:11 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/commands/trigger.h,v 1.74 2009/07/28 02:56:31 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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,
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index ca9913bda3b88583fbf14201d52b210000a965a9..37164f3b5d1f177e05e838c7355ac844d1fd5742 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.114 2009/06/11 14:49:13 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.115 2009/07/28 02:56:31 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -58,6 +58,7 @@ typedef struct Trigger
 	char		tgenabled;
 	bool		tgisconstraint;
 	Oid			tgconstrrelid;
+	Oid			tgconstrindid;
 	Oid			tgconstraint;
 	bool		tgdeferrable;
 	bool		tginitdeferred;