mirror of
https://github.com/postgres/postgres.git
synced 2025-11-09 06:21:09 +03:00
Add tgconstrrelid to stored Trigger structures, make RI trigger functions
depend on this rather than the trigger argument strings to locate the other relation to test. This makes RI triggers function properly in the presence of schemas and temp tables. Along the way, fix bogus lack of locking in RI triggers, handle quoting of names fully correctly, compute required sizes of query buffers with some semblance of accuracy.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.170 2002/04/01 04:35:38 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.171 2002/04/01 22:36:09 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The PerformAddAttribute() code, like most of the relation
|
||||
@@ -1639,9 +1639,6 @@ AlterTableAddConstraint(Oid myrelid,
|
||||
!isTempNamespace(RelationGetNamespace(rel)))
|
||||
elog(ERROR, "ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint.");
|
||||
|
||||
/* Don't need pkrel open anymore, but hold lock */
|
||||
heap_close(pkrel, NoLock);
|
||||
|
||||
/*
|
||||
* First we check for limited correctness of the
|
||||
* constraint.
|
||||
@@ -1651,34 +1648,30 @@ AlterTableAddConstraint(Oid myrelid,
|
||||
* referenced relation, and that the column datatypes
|
||||
* are comparable.
|
||||
*
|
||||
* Scan through each tuple, calling the RI_FKey_Match_Ins
|
||||
* Scan through each tuple, calling RI_FKey_check_ins
|
||||
* (insert trigger) as if that tuple had just been
|
||||
* inserted. If any of those fail, it should
|
||||
* elog(ERROR) and that's that.
|
||||
*/
|
||||
|
||||
trig.tgoid = 0;
|
||||
MemSet(&trig, 0, sizeof(trig));
|
||||
trig.tgoid = InvalidOid;
|
||||
if (fkconstraint->constr_name)
|
||||
trig.tgname = fkconstraint->constr_name;
|
||||
else
|
||||
trig.tgname = "<unknown>";
|
||||
trig.tgfoid = 0;
|
||||
trig.tgtype = 0;
|
||||
trig.tgenabled = TRUE;
|
||||
trig.tgisconstraint = TRUE;
|
||||
trig.tginitdeferred = FALSE;
|
||||
trig.tgconstrrelid = RelationGetRelid(pkrel);
|
||||
trig.tgdeferrable = FALSE;
|
||||
trig.tginitdeferred = FALSE;
|
||||
|
||||
trig.tgargs = (char **) palloc(
|
||||
sizeof(char *) * (4 + length(fkconstraint->fk_attrs)
|
||||
+ length(fkconstraint->pk_attrs)));
|
||||
|
||||
if (fkconstraint->constr_name)
|
||||
trig.tgargs[0] = fkconstraint->constr_name;
|
||||
else
|
||||
trig.tgargs[0] = "<unknown>";
|
||||
trig.tgargs[1] = pstrdup(RelationGetRelationName(rel));
|
||||
trig.tgargs[2] = fkconstraint->pktable->relname;
|
||||
trig.tgargs[0] = trig.tgname;
|
||||
trig.tgargs[1] = RelationGetRelationName(rel);
|
||||
trig.tgargs[2] = RelationGetRelationName(pkrel);
|
||||
trig.tgargs[3] = fkconstraint->match_type;
|
||||
count = 4;
|
||||
foreach(list, fkconstraint->fk_attrs)
|
||||
@@ -1732,6 +1725,9 @@ AlterTableAddConstraint(Oid myrelid,
|
||||
heap_endscan(scan);
|
||||
|
||||
pfree(trig.tgargs);
|
||||
|
||||
heap_close(pkrel, NoLock);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.110 2002/03/31 06:26:30 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.111 2002/04/01 22:36:10 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -544,6 +544,7 @@ RelationBuildTriggers(Relation relation)
|
||||
build->tgtype = pg_trigger->tgtype;
|
||||
build->tgenabled = pg_trigger->tgenabled;
|
||||
build->tgisconstraint = pg_trigger->tgisconstraint;
|
||||
build->tgconstrrelid = pg_trigger->tgconstrrelid;
|
||||
build->tgdeferrable = pg_trigger->tgdeferrable;
|
||||
build->tginitdeferred = pg_trigger->tginitdeferred;
|
||||
build->tgnargs = pg_trigger->tgnargs;
|
||||
@@ -763,6 +764,8 @@ equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
|
||||
return false;
|
||||
if (trig1->tgisconstraint != trig2->tgisconstraint)
|
||||
return false;
|
||||
if (trig1->tgconstrrelid != trig2->tgconstrrelid)
|
||||
return false;
|
||||
if (trig1->tgdeferrable != trig2->tgdeferrable)
|
||||
return false;
|
||||
if (trig1->tginitdeferred != trig2->tginitdeferred)
|
||||
|
||||
Reference in New Issue
Block a user