diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index a5b327d942e..a70c11aa889 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -1,4 +1,4 @@
-
+
@@ -1748,6 +1748,14 @@
The domain this constraint is on; 0 if not a domain constraint
+
+ conindid
+ oid
+ pg_class.oid
+ The index supporting this constraint, if it's a unique, primary
+ key, or foreign key constraint; else 0
+
+
confrelid
oid
@@ -4510,6 +4518,13 @@
The table referenced by a referential integrity constraint
+
+ tgconstrindid
+ oid
+ pg_class.oid
+ The index supporting a unique, primary key, or referential integrity constraint
+
+
tgconstraint
oid
@@ -4560,6 +4575,7 @@
When tgconstraint> is nonzero,
tgisconstraint> must be true, and
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
diff --git a/doc/src/sgml/trigger.sgml b/doc/src/sgml/trigger.sgml
index 473e107c840..348434f9174 100644
--- a/doc/src/sgml/trigger.sgml
+++ b/doc/src/sgml/trigger.sgml
@@ -1,4 +1,4 @@
-
+
Triggers
@@ -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
where tgname> is the trigger's name,
- tgnargs> is number of arguments in
+ tgnargs> is the number of arguments in
tgargs>, and tgargs> is an array of
pointers to the arguments specified in the CREATE
TRIGGER statement. The other members are for internal use
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index f4cf829b468..588c26ad125 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 b75aac04e17..0199ca67303 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 cea4f797757..36f5b62b4e0 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 e6756b7477c..81c35100c7b 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 20253e1523f..e883e8ed91f 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 bb628ed80a3..0cc33aae6b6 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 659b5914239..1d3077cc324 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 e3677c51d61..126a079f3e4 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 ef7f3927879..ecbf1056063 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 24454ef5687..08305e68b65 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 2f4274107fe..64730bc60f1 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 7e886eede41..3e14bbe3baa 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 ca9913bda3b..37164f3b5d1 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;