|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * 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 $ |
12 | 12 | *
|
13 | 13 | * NOTES
|
14 | 14 | * The PortalExecutorHeapMemory crap needs to be eliminated
|
|
34 | 34 | #include"commands/rename.h"
|
35 | 35 | #include"executor/execdefs.h"
|
36 | 36 | #include"executor/executor.h"
|
| 37 | +#include"executor/spi.h" |
37 | 38 | #include"catalog/heap.h"
|
38 | 39 | #include"miscadmin.h"
|
39 | 40 | #include"optimizer/prep.h"
|
40 | 41 | #include"utils/acl.h"
|
41 | 42 | #include"utils/builtins.h"
|
42 | 43 | #include"utils/syscache.h"
|
43 | 44 | #include"utils/temprel.h"
|
44 |
| - |
| 45 | +#include"commands/trigger.h" |
45 | 46 |
|
46 | 47 | /* ----------------
|
47 | 48 | *PortalExecutorHeapMemory stuff
|
@@ -688,7 +689,95 @@ void
|
688 | 689 | AlterTableAddConstraint(constchar*relationName,
|
689 | 690 | boolinh,Node*newConstraint)
|
690 | 691 | {
|
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 | +caseT_Constraint: |
| 698 | +elog(ERROR,"ALTER TABLE / ADD CONSTRAINT is not implemented"); |
| 699 | +caseT_FkConstraint: |
| 700 | +{ |
| 701 | +FkConstraint*fkconstraint=(FkConstraint*)newConstraint; |
| 702 | +Relationrel,classrel; |
| 703 | +HeapScanDescscan; |
| 704 | +HeapTupletuple; |
| 705 | +Triggertrig; |
| 706 | +List*list; |
| 707 | +intcount; |
| 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 | +TriggerDatanewtrigdata; |
| 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 | +} |
692 | 781 | }
|
693 | 782 |
|
694 | 783 |
|
|