diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/catalog/heap.c | 4 | ||||
-rw-r--r-- | src/backend/catalog/index.c | 4 | ||||
-rw-r--r-- | src/backend/catalog/information_schema.sql | 19 | ||||
-rw-r--r-- | src/backend/catalog/pg_constraint.c | 11 | ||||
-rw-r--r-- | src/backend/commands/tablecmds.c | 30 | ||||
-rw-r--r-- | src/backend/commands/trigger.c | 17 | ||||
-rw-r--r-- | src/backend/commands/typecmds.c | 4 | ||||
-rw-r--r-- | src/backend/tcop/utility.c | 5 |
8 files changed, 52 insertions, 42 deletions
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: |