|
7 | 7 | * |
8 | 8 | * |
9 | 9 | * IDENTIFICATION |
10 | | - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.64 2000/01/22 14:20:45 petere Exp $ |
| 10 | + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.65 2000/01/24 23:40:35 petere Exp $ |
11 | 11 | * |
12 | 12 | * NOTES |
13 | 13 | * The PortalExecutorHeapMemory crap needs to be eliminated |
@@ -672,209 +672,13 @@ drop_default(Oid relid, int16 attnum) |
672 | 672 |
|
673 | 673 | /* |
674 | 674 | * ALTER TABLE DROP COLUMN |
675 | | - * |
676 | | - * Strategy: |
677 | | - * - permission/sanity checks |
678 | | - * - create a new table _ATDC<name> with all attributes minus the desired one |
679 | | - * - copy over all the data |
680 | | - * - make the column defaults point to the new table |
681 | | - * - kill the old table |
682 | | - * - rename the intermediate table back |
683 | 675 | */ |
684 | 676 | void |
685 | 677 | AlterTableDropColumn(constchar*relationName, |
686 | 678 | boolinh,constchar*colName, |
687 | 679 | intbehavior) |
688 | 680 | { |
689 | | -Relationoldrel,newrel,defrel; |
690 | | -HeapTupletuple; |
691 | | -TupleDescolddesc,newdesc,defdsc; |
692 | | -int16dropattnum,oldnumatts; |
693 | | -Oidoldrel_oid,newrel_oid; |
694 | | -chartmpname[NAMEDATALEN]; |
695 | | -int16i; |
696 | | -HeapScanDescscan; |
697 | | -ScanKeyDatascankey; |
698 | | - |
699 | | -if (!allowSystemTableMods&&IsSystemRelationName(relationName)) |
700 | | -elog(ERROR,"ALTER TABLE: relation \"%s\" is a system catalog", |
701 | | -relationName); |
702 | | -#ifndefNO_SECURITY |
703 | | -if (!pg_ownercheck(UserName,relationName,RELNAME)) |
704 | | -elog(ERROR,"ALTER TABLE: permission denied"); |
705 | | -#endif |
706 | | - |
707 | | -oldrel=heap_openr(relationName,AccessExclusiveLock); |
708 | | -if (oldrel->rd_rel->relkind!=RELKIND_RELATION) |
709 | | - { |
710 | | -heap_close(oldrel,AccessExclusiveLock); |
711 | | -elog(ERROR,"ALTER TABLE: relation %s is not a table",relationName); |
712 | | - } |
713 | | - |
714 | | -oldrel_oid=ObjectIdGetDatum(RelationGetRelid(oldrel)); |
715 | | -oldnumatts=RelationGetNumberOfAttributes(oldrel); |
716 | | - |
717 | | -if (oldnumatts==1) |
718 | | - { |
719 | | -heap_close(oldrel,AccessExclusiveLock); |
720 | | -elog(ERROR,"ALTER TABLE: relation %s only has one column",relationName); |
721 | | - } |
722 | | - |
723 | | -/* What to do here? */ |
724 | | -/* |
725 | | - if (length(find_all_inheritors(RelationGetRelid(oldrel)))>0) |
726 | | - elog(ERROR, "ALTER TABLE: cannot drop a column on table that is inherited from"); |
727 | | -*/ |
728 | | -/* |
729 | | - * get the number of the attribute |
730 | | - */ |
731 | | -tuple=SearchSysCacheTuple(ATTNAME,oldrel_oid,NameGetDatum(namein(colName)),0,0); |
732 | | -if (!HeapTupleIsValid(tuple)) |
733 | | - { |
734 | | -heap_close(oldrel,AccessExclusiveLock); |
735 | | -elog(ERROR,"ALTER TABLE: relation \"%s\" has no column \"%s\"", |
736 | | -relationName,colName); |
737 | | - } |
738 | | - |
739 | | -dropattnum= ((Form_pg_attribute)GETSTRUCT(tuple))->attnum; |
740 | | - |
741 | | -if (snprintf(tmpname,NAMEDATALEN,"_ATDC%s",relationName)==-1) |
742 | | - { |
743 | | -heap_close(oldrel,AccessExclusiveLock); |
744 | | -elog(ERROR,"AlterTableDropColumn: relation name too long"); |
745 | | - } |
746 | | - |
747 | | -/* |
748 | | - * Build descriptor for new relation |
749 | | - */ |
750 | | -olddesc=RelationGetDescr(oldrel); |
751 | | - |
752 | | -newdesc=CreateTemplateTupleDesc(oldnumatts-1); |
753 | | -for(i=1;i<dropattnum;i++) |
754 | | - { |
755 | | -Form_pg_attributeatt=olddesc->attrs[i-1]; |
756 | | -TupleDescInitEntry(newdesc,i,nameout(&(att->attname)), |
757 | | -att->atttypid,att->atttypmod, |
758 | | -att->attnelems,att->attisset); |
759 | | -/* the above function doesn't take care of these two */ |
760 | | -newdesc->attrs[i-1]->attnotnull=att->attnotnull; |
761 | | -newdesc->attrs[i-1]->atthasdef=att->atthasdef; |
762 | | - } |
763 | | - |
764 | | -for(i=dropattnum;i <=oldnumatts-1;i++) |
765 | | - { |
766 | | -Form_pg_attributeatt=olddesc->attrs[i]; |
767 | | -TupleDescInitEntry(newdesc,i,nameout(&(att->attname)), |
768 | | -att->atttypid,att->atttypmod, |
769 | | -att->attnelems,att->attisset); |
770 | | -/* the above function doesn't take care of these two */ |
771 | | -newdesc->attrs[i-1]->attnotnull=att->attnotnull; |
772 | | -newdesc->attrs[i-1]->atthasdef=att->atthasdef; |
773 | | - } |
774 | | - |
775 | | -/* Create the new table */ |
776 | | -newrel_oid=heap_create_with_catalog(tmpname,newdesc,RELKIND_RELATION, false); |
777 | | -if (newrel_oid==InvalidOid) |
778 | | - { |
779 | | -heap_close(oldrel,AccessExclusiveLock); |
780 | | -elog(ERROR,"ALTER TABLE: something went wrong"); |
781 | | - } |
782 | | - |
783 | | -/* Make the new table visible */ |
784 | | -CommandCounterIncrement(); |
785 | | - |
786 | | -/* |
787 | | - * Copy over the data |
788 | | - */ |
789 | | -newrel=heap_open(newrel_oid,AccessExclusiveLock); |
790 | | - |
791 | | -scan=heap_beginscan(oldrel, false,SnapshotNow,0,NULL); |
792 | | -while (HeapTupleIsValid(tuple=heap_getnext(scan,0))) |
793 | | - { |
794 | | -boolisnull; |
795 | | -Datum*new_record; |
796 | | -bool*new_record_nulls; |
797 | | -HeapTuplenew_tuple; |
798 | | - |
799 | | -new_record=palloc((oldnumatts-1)*sizeof(*new_record)); |
800 | | -new_record_nulls=palloc((oldnumatts-1)*sizeof(*new_record_nulls)); |
801 | | - |
802 | | -for(i=1;i<dropattnum;i++) |
803 | | - { |
804 | | -new_record[i-1]=heap_getattr(tuple,i,olddesc,&isnull); |
805 | | -new_record_nulls[i-1]=isnull ?'n' :' '; |
806 | | - } |
807 | | -for(i=dropattnum+1;i <=oldnumatts;i++) |
808 | | - { |
809 | | -new_record[i-2]=heap_getattr(tuple,i,olddesc,&isnull); |
810 | | -new_record_nulls[i-2]=isnull ?'n' :' '; |
811 | | - } |
812 | | - |
813 | | -new_tuple=heap_formtuple(newdesc,new_record,new_record_nulls); |
814 | | -Assert(new_tuple); |
815 | | - |
816 | | -if (heap_insert(newrel,new_tuple)==InvalidOid) |
817 | | -elog(ERROR,"AlterTableDropColumn: heap_insert failed"); |
818 | | - |
819 | | -pfree(new_record); |
820 | | -pfree(new_record_nulls); |
821 | | - } |
822 | | -heap_endscan(scan); |
823 | | - |
824 | | -heap_close(newrel,NoLock); |
825 | | -heap_close(oldrel,NoLock); |
826 | | - |
827 | | -/* |
828 | | - * Move defaults over to the new table |
829 | | - */ |
830 | | -defrel=heap_openr(AttrDefaultRelationName,AccessExclusiveLock); |
831 | | -defdsc=RelationGetDescr(defrel); |
832 | | - |
833 | | -/* look for all entries referencing the old table */ |
834 | | -ScanKeyEntryInitialize(&scankey,0x0,Anum_pg_attrdef_adrelid,F_OIDEQ, |
835 | | -ObjectIdGetDatum(oldrel_oid)); |
836 | | -scan=heap_beginscan(defrel, false,SnapshotNow,1,&scankey); |
837 | | -while(HeapTupleIsValid(tuple=heap_getnext(scan, false))) |
838 | | - { |
839 | | -HeapTuplenewtuple; |
840 | | -int2attrnum; |
841 | | -Relationirelations[Num_pg_attrdef_indices]; |
842 | | - |
843 | | -attrnum= ((Form_pg_attrdef)GETSTRUCT(tuple))->adnum; |
844 | | - |
845 | | -/* remove the entry about the dropped column */ |
846 | | -if (attrnum==dropattnum) |
847 | | - { |
848 | | -heap_delete(defrel,&tuple->t_self,NULL); |
849 | | -continue; |
850 | | - } |
851 | | - |
852 | | -newtuple=heap_copytuple(tuple); |
853 | | - |
854 | | -if (attrnum>dropattnum) |
855 | | - ((Form_pg_attrdef)GETSTRUCT(newtuple))->adnum--; |
856 | | - |
857 | | -/* make it point to the new table */ |
858 | | - ((Form_pg_attrdef)GETSTRUCT(newtuple))->adrelid=newrel_oid; |
859 | | -heap_update(defrel,&tuple->t_self,newtuple,NULL); |
860 | | - |
861 | | -/* keep the system catalog indices current */ |
862 | | -CatalogOpenIndices(Num_pg_attrdef_indices,Name_pg_attrdef_indices,irelations); |
863 | | -CatalogIndexInsert(irelations,Num_pg_attrdef_indices,defrel,newtuple); |
864 | | -CatalogCloseIndices(Num_pg_attrdef_indices,irelations); |
865 | | - } |
866 | | -heap_endscan(scan); |
867 | | -heap_close(defrel,NoLock); |
868 | | - |
869 | | -CommandCounterIncrement(); |
870 | | - |
871 | | -/* make the old table disappear */ |
872 | | -heap_drop_with_catalog(relationName); |
873 | | -CommandCounterIncrement(); |
874 | | - |
875 | | -/* set back original name */ |
876 | | -TypeRename(tmpname,relationName); |
877 | | -renamerel(tmpname,relationName); |
| 681 | +elog(ERROR,"ALTER TABLE / DROP COLUMN is not implemented"); |
878 | 682 | } |
879 | 683 |
|
880 | 684 |
|
|