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;