*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.157 2005/05/10 13:16:26 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.158 2005/05/30 06:52:38 neilc Exp $
*
*-------------------------------------------------------------------------
*/
pfree(trig.tgargs);
}
-/*
- * Create the triggers that implement an FK constraint.
- */
static void
-createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
- Oid constrOid)
+CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint,
+ ObjectAddress *constrobj, ObjectAddress *trigobj,
+ bool on_insert)
{
- RangeVar *myRel;
CreateTrigStmt *fk_trigger;
ListCell *fk_attr;
ListCell *pk_attr;
- ObjectAddress trigobj,
- constrobj;
-
- /*
- * Reconstruct a RangeVar for my relation (not passed in,
- * unfortunately).
- */
- myRel = makeRangeVar(get_namespace_name(RelationGetNamespace(rel)),
- pstrdup(RelationGetRelationName(rel)));
- /*
- * Preset objectAddress fields
- */
- constrobj.classId = ConstraintRelationId;
- constrobj.objectId = constrOid;
- constrobj.objectSubId = 0;
- trigobj.classId = TriggerRelationId;
- trigobj.objectSubId = 0;
-
- /* Make changes-so-far visible */
- CommandCounterIncrement();
-
- /*
- * Build and execute a CREATE CONSTRAINT TRIGGER statement for the
- * CHECK action.
- */
fk_trigger = makeNode(CreateTrigStmt);
fk_trigger->trigname = fkconstraint->constr_name;
fk_trigger->relation = myRel;
- fk_trigger->funcname = SystemFuncName("RI_FKey_check_ins");
fk_trigger->before = false;
fk_trigger->row = true;
- fk_trigger->actions[0] = 'i';
- fk_trigger->actions[1] = 'u';
- fk_trigger->actions[2] = '\0';
+
+ /* Either ON INSERT or ON UPDATE */
+ if (on_insert)
+ {
+ fk_trigger->funcname = SystemFuncName("RI_FKey_check_ins");
+ fk_trigger->actions[0] = 'i';
+ }
+ else
+ {
+ fk_trigger->funcname = SystemFuncName("RI_FKey_check_upd");
+ fk_trigger->actions[0] = 'u';
+ }
+ fk_trigger->actions[1] = '\0';
fk_trigger->isconstraint = true;
fk_trigger->deferrable = fkconstraint->deferrable;
fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
}
- trigobj.objectId = CreateTrigger(fk_trigger, true);
+ trigobj->objectId = CreateTrigger(fk_trigger, true);
/* Register dependency from trigger to constraint */
- recordDependencyOn(&trigobj, &constrobj, DEPENDENCY_INTERNAL);
+ recordDependencyOn(trigobj, constrobj, DEPENDENCY_INTERNAL);
/* Make changes-so-far visible */
CommandCounterIncrement();
+}
+
+/*
+ * Create the triggers that implement an FK constraint.
+ */
+static void
+createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
+ Oid constrOid)
+{
+ RangeVar *myRel;
+ CreateTrigStmt *fk_trigger;
+ ListCell *fk_attr;
+ ListCell *pk_attr;
+ ObjectAddress trigobj,
+ constrobj;
+
+ /*
+ * Reconstruct a RangeVar for my relation (not passed in,
+ * unfortunately).
+ */
+ myRel = makeRangeVar(get_namespace_name(RelationGetNamespace(rel)),
+ pstrdup(RelationGetRelationName(rel)));
+
+ /*
+ * Preset objectAddress fields
+ */
+ constrobj.classId = ConstraintRelationId;
+ constrobj.objectId = constrOid;
+ constrobj.objectSubId = 0;
+ trigobj.classId = TriggerRelationId;
+ trigobj.objectSubId = 0;
+
+ /* Make changes-so-far visible */
+ CommandCounterIncrement();
+
+ /*
+ * Build and execute a CREATE CONSTRAINT TRIGGER statement for the
+ * CHECK action for both INSERTs and UPDATEs on the referencing table.
+ */
+ CreateFKCheckTrigger(myRel, fkconstraint, &constrobj, &trigobj, true);
+ CreateFKCheckTrigger(myRel, fkconstraint, &constrobj, &trigobj, false);
/*
* Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON