Skip to content

Commit ddd596d

Browse files
Jan WieckJan Wieck
authored andcommitted
Added ALTER TABLE ... ADD CONSTRAINT (provided by Stephan Szabo).
Added constraint dumping capability to pg_dump (also from Stephan) Fixed DROP TABLE -> RelationBuildTriggers: 2 record(s) not found for rel error. Fixed little error in gram.y I made the last days. Jan
1 parent 74d53d7 commit ddd596d

File tree

5 files changed

+450
-28
lines changed

5 files changed

+450
-28
lines changed

src/backend/commands/command.c

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.67 2000/01/29 16:58:34 petere Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.68 2000/02/04 18:49:31 wieck Exp $
1212
*
1313
* NOTES
1414
* The PortalExecutorHeapMemory crap needs to be eliminated
@@ -34,14 +34,15 @@
3434
#include "commands/rename.h"
3535
#include "executor/execdefs.h"
3636
#include "executor/executor.h"
37+
#include "executor/spi.h"
3738
#include "catalog/heap.h"
3839
#include "miscadmin.h"
3940
#include "optimizer/prep.h"
4041
#include "utils/acl.h"
4142
#include "utils/builtins.h"
4243
#include "utils/syscache.h"
4344
#include "utils/temprel.h"
44-
45+
#include "commands/trigger.h"
4546

4647
/* ----------------
4748
* PortalExecutorHeapMemory stuff
@@ -688,7 +689,95 @@ void
688689
AlterTableAddConstraint(const char *relationName,
689690
bool inh, Node *newConstraint)
690691
{
691-
elog(ERROR, "ALTER TABLE / ADD CONSTRAINT is not implemented");
692+
if (newConstraint == NULL)
693+
elog(ERROR, "ALTER TABLE / ADD CONSTRAINT passed invalid constraint.");
694+
695+
switch (nodeTag(newConstraint))
696+
{
697+
case T_Constraint:
698+
elog(ERROR, "ALTER TABLE / ADD CONSTRAINT is not implemented");
699+
case T_FkConstraint:
700+
{
701+
FkConstraint *fkconstraint=(FkConstraint *)newConstraint;
702+
Relation rel, classrel;
703+
HeapScanDesc scan;
704+
HeapTuple tuple;
705+
Trigger trig;
706+
List *list;
707+
int count;
708+
709+
/*
710+
* Grab an exclusive lock on the pk table, so that someone
711+
* doesn't delete rows out from under us.
712+
*/
713+
714+
rel = heap_openr(fkconstraint->pktable_name, AccessExclusiveLock);
715+
heap_close(rel, NoLock);
716+
717+
/*
718+
* Grab an exclusive lock on the fk table, and then scan through
719+
* each tuple, calling the RI_FKey_Match_Ins (insert trigger)
720+
* as if that tuple had just been inserted. If any of those
721+
* fail, it should elog(ERROR) and that's that.
722+
*/
723+
rel = heap_openr(relationName, AccessExclusiveLock);
724+
trig.tgoid = 0;
725+
trig.tgname = "<unknown>";
726+
trig.tgfoid = 0;
727+
trig.tgtype = 0;
728+
trig.tgenabled = TRUE;
729+
trig.tgisconstraint = TRUE;
730+
trig.tginitdeferred = FALSE;
731+
trig.tgdeferrable = FALSE;
732+
733+
trig.tgargs = (char **)palloc(
734+
sizeof(char *) * (4 + length(fkconstraint->fk_attrs)
735+
+ length(fkconstraint->pk_attrs)));
736+
737+
trig.tgargs[0] = "<unnamed>";
738+
trig.tgargs[1] = (char *)relationName;
739+
trig.tgargs[2] = fkconstraint->pktable_name;
740+
trig.tgargs[3] = fkconstraint->match_type;
741+
count = 4;
742+
foreach (list, fkconstraint->fk_attrs)
743+
{
744+
Ident *fk_at = lfirst(list);
745+
trig.tgargs[count++] = fk_at->name;
746+
}
747+
foreach (list, fkconstraint->pk_attrs)
748+
{
749+
Ident *pk_at = lfirst(list);
750+
trig.tgargs[count++] = pk_at->name;
751+
}
752+
trig.tgnargs = count;
753+
754+
scan = heap_beginscan(rel, false, SnapshotNow, 0, NULL);
755+
AssertState(scan!=NULL);
756+
757+
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
758+
{
759+
TriggerData newtrigdata;
760+
newtrigdata.tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW;
761+
newtrigdata.tg_relation = rel;
762+
newtrigdata.tg_trigtuple = tuple;
763+
newtrigdata.tg_newtuple = NULL;
764+
newtrigdata.tg_trigger = &trig;
765+
766+
CurrentTriggerData = &newtrigdata;
767+
768+
RI_FKey_check_ins(NULL);
769+
770+
/* Make a call to the check function */
771+
}
772+
heap_endscan(scan);
773+
heap_close(rel, NoLock); /* close rel but keep lock! */
774+
775+
pfree(trig.tgargs);
776+
}
777+
break;
778+
default:
779+
elog(ERROR, "ALTER TABLE / ADD CONSTRAINT unable to determine type of constraint passed");
780+
}
692781
}
693782

694783

src/backend/commands/trigger.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.56 2000/01/31 04:35:49 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.57 2000/02/04 18:49:31 wieck Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -399,6 +399,15 @@ RelationRemoveTriggers(Relation rel)
399399

400400
DropTrigger(&stmt);
401401

402+
/* ----------
403+
* Need to do a command counter increment here to show up
404+
* new pg_class.reltriggers in the next loop invocation already
405+
* (there are multiple referential integrity action
406+
* triggers for the same FK table defined on the PK table).
407+
* ----------
408+
*/
409+
CommandCounterIncrement();
410+
402411
pfree(stmt.relname);
403412
pfree(stmt.trigname);
404413
}

0 commit comments

Comments
 (0)