|
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(const char *relationName,
|
689 | 690 | bool inh, 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 | + 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 | + } |
692 | 781 | }
|
693 | 782 |
|
694 | 783 |
|
|
0 commit comments