Create separate ON INSERT and ON UPDATE triggers on tables with foreign
keys, rather than a single trigger for both events. This should not change functionality, but it is more consistent: previously, there were trigger functions for both "check_insert" and "check_update", but the former was used for both events. Bump catalog version number (not strictly necessary, but best to be cautious).
This commit is contained in:
parent
0832fb74df
commit
f99b75b0a0
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -4380,6 +4380,69 @@ validateForeignKeyConstraint(FkConstraint *fkconstraint,
|
|||||||
pfree(trig.tgargs);
|
pfree(trig.tgargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint,
|
||||||
|
ObjectAddress *constrobj, ObjectAddress *trigobj,
|
||||||
|
bool on_insert)
|
||||||
|
{
|
||||||
|
CreateTrigStmt *fk_trigger;
|
||||||
|
ListCell *fk_attr;
|
||||||
|
ListCell *pk_attr;
|
||||||
|
|
||||||
|
fk_trigger = makeNode(CreateTrigStmt);
|
||||||
|
fk_trigger->trigname = fkconstraint->constr_name;
|
||||||
|
fk_trigger->relation = myRel;
|
||||||
|
fk_trigger->before = false;
|
||||||
|
fk_trigger->row = true;
|
||||||
|
|
||||||
|
/* 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->initdeferred = fkconstraint->initdeferred;
|
||||||
|
fk_trigger->constrrel = fkconstraint->pktable;
|
||||||
|
|
||||||
|
fk_trigger->args = NIL;
|
||||||
|
fk_trigger->args = lappend(fk_trigger->args,
|
||||||
|
makeString(fkconstraint->constr_name));
|
||||||
|
fk_trigger->args = lappend(fk_trigger->args,
|
||||||
|
makeString(myRel->relname));
|
||||||
|
fk_trigger->args = lappend(fk_trigger->args,
|
||||||
|
makeString(fkconstraint->pktable->relname));
|
||||||
|
fk_trigger->args = lappend(fk_trigger->args,
|
||||||
|
makeString(fkMatchTypeToString(fkconstraint->fk_matchtype)));
|
||||||
|
if (list_length(fkconstraint->fk_attrs) != list_length(fkconstraint->pk_attrs))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_FOREIGN_KEY),
|
||||||
|
errmsg("number of referencing and referenced columns for foreign key disagree")));
|
||||||
|
|
||||||
|
forboth(fk_attr, fkconstraint->fk_attrs,
|
||||||
|
pk_attr, fkconstraint->pk_attrs)
|
||||||
|
{
|
||||||
|
fk_trigger->args = lappend(fk_trigger->args, lfirst(fk_attr));
|
||||||
|
fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
|
||||||
|
}
|
||||||
|
|
||||||
|
trigobj->objectId = CreateTrigger(fk_trigger, true);
|
||||||
|
|
||||||
|
/* Register dependency from trigger to constraint */
|
||||||
|
recordDependencyOn(trigobj, constrobj, DEPENDENCY_INTERNAL);
|
||||||
|
|
||||||
|
/* Make changes-so-far visible */
|
||||||
|
CommandCounterIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the triggers that implement an FK constraint.
|
* Create the triggers that implement an FK constraint.
|
||||||
*/
|
*/
|
||||||
@ -4415,51 +4478,10 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Build and execute a CREATE CONSTRAINT TRIGGER statement for the
|
* Build and execute a CREATE CONSTRAINT TRIGGER statement for the
|
||||||
* CHECK action.
|
* CHECK action for both INSERTs and UPDATEs on the referencing table.
|
||||||
*/
|
*/
|
||||||
fk_trigger = makeNode(CreateTrigStmt);
|
CreateFKCheckTrigger(myRel, fkconstraint, &constrobj, &trigobj, true);
|
||||||
fk_trigger->trigname = fkconstraint->constr_name;
|
CreateFKCheckTrigger(myRel, fkconstraint, &constrobj, &trigobj, false);
|
||||||
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';
|
|
||||||
|
|
||||||
fk_trigger->isconstraint = true;
|
|
||||||
fk_trigger->deferrable = fkconstraint->deferrable;
|
|
||||||
fk_trigger->initdeferred = fkconstraint->initdeferred;
|
|
||||||
fk_trigger->constrrel = fkconstraint->pktable;
|
|
||||||
|
|
||||||
fk_trigger->args = NIL;
|
|
||||||
fk_trigger->args = lappend(fk_trigger->args,
|
|
||||||
makeString(fkconstraint->constr_name));
|
|
||||||
fk_trigger->args = lappend(fk_trigger->args,
|
|
||||||
makeString(myRel->relname));
|
|
||||||
fk_trigger->args = lappend(fk_trigger->args,
|
|
||||||
makeString(fkconstraint->pktable->relname));
|
|
||||||
fk_trigger->args = lappend(fk_trigger->args,
|
|
||||||
makeString(fkMatchTypeToString(fkconstraint->fk_matchtype)));
|
|
||||||
if (list_length(fkconstraint->fk_attrs) != list_length(fkconstraint->pk_attrs))
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_INVALID_FOREIGN_KEY),
|
|
||||||
errmsg("number of referencing and referenced columns for foreign key disagree")));
|
|
||||||
|
|
||||||
forboth(fk_attr, fkconstraint->fk_attrs,
|
|
||||||
pk_attr, fkconstraint->pk_attrs)
|
|
||||||
{
|
|
||||||
fk_trigger->args = lappend(fk_trigger->args, lfirst(fk_attr));
|
|
||||||
fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
|
|
||||||
}
|
|
||||||
|
|
||||||
trigobj.objectId = CreateTrigger(fk_trigger, true);
|
|
||||||
|
|
||||||
/* Register dependency from trigger to constraint */
|
|
||||||
recordDependencyOn(&trigobj, &constrobj, DEPENDENCY_INTERNAL);
|
|
||||||
|
|
||||||
/* Make changes-so-far visible */
|
|
||||||
CommandCounterIncrement();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
|
* Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.270 2005/05/30 01:20:50 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.271 2005/05/30 06:52:38 neilc Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200505291
|
#define CATALOG_VERSION_NO 200505301
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user