Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit ddd596d

Browse files
Jan WieckJan Wieck
Jan Wieck
authored and
Jan Wieck
committed
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)