|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.68 2003/03/2003:34:55 momjian Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.69 2003/03/2018:52:47 momjian Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -3795,6 +3795,90 @@ CheckTupleType(Form_pg_class tuple_class)
|
3795 | 3795 | }
|
3796 | 3796 | }
|
3797 | 3797 |
|
| 3798 | +/* |
| 3799 | + * ALTER TABLE CLUSTER ON |
| 3800 | + * |
| 3801 | + * The only thing we have to do is to change the indisclustered bits. |
| 3802 | + */ |
| 3803 | +void |
| 3804 | +AlterTableClusterOn(OidrelOid,constchar*indexName) |
| 3805 | +{ |
| 3806 | +Relationrel, |
| 3807 | +pg_index; |
| 3808 | +List*index; |
| 3809 | +OidindexOid; |
| 3810 | +HeapTupleindexTuple; |
| 3811 | +Form_pg_indexindexForm; |
| 3812 | + |
| 3813 | +rel=heap_open(relOid,AccessExclusiveLock); |
| 3814 | + |
| 3815 | +indexOid=get_relname_relid(indexName,rel->rd_rel->relnamespace); |
| 3816 | + |
| 3817 | +if (!OidIsValid(indexOid)) |
| 3818 | +elog(ERROR,"ALTER TABLE: cannot find index \"%s\" for table \"%s\"", |
| 3819 | +indexName,NameStr(rel->rd_rel->relname)); |
| 3820 | + |
| 3821 | +indexTuple=SearchSysCache(INDEXRELID, |
| 3822 | +ObjectIdGetDatum(indexOid), |
| 3823 | +0,0,0); |
| 3824 | + |
| 3825 | +if (!HeapTupleIsValid(indexTuple)) |
| 3826 | +elog(ERROR,"Cache lookup failed for index %u", |
| 3827 | +indexOid); |
| 3828 | +indexForm= (Form_pg_index)GETSTRUCT(indexTuple); |
| 3829 | + |
| 3830 | +/* |
| 3831 | + * If this is the same index the relation was previously |
| 3832 | + * clustered on, no need to do anything. |
| 3833 | + */ |
| 3834 | +if (indexForm->indisclustered) |
| 3835 | +{ |
| 3836 | +elog(NOTICE,"ALTER TABLE: table \"%s\" is already being clustered on index \"%s\"", |
| 3837 | +NameStr(rel->rd_rel->relname),indexName); |
| 3838 | +heap_close(rel,AccessExclusiveLock); |
| 3839 | +return; |
| 3840 | +} |
| 3841 | + |
| 3842 | +pg_index=heap_openr(IndexRelationName,RowExclusiveLock); |
| 3843 | + |
| 3844 | +/* |
| 3845 | + * Now check each index in the relation and set the bit where needed. |
| 3846 | + */ |
| 3847 | +foreach (index,RelationGetIndexList(rel)) |
| 3848 | +{ |
| 3849 | +HeapTupleidxtuple; |
| 3850 | +Form_pg_indexidxForm; |
| 3851 | + |
| 3852 | +indexOid=lfirsto(index); |
| 3853 | +idxtuple=SearchSysCacheCopy(INDEXRELID, |
| 3854 | +ObjectIdGetDatum(indexOid), |
| 3855 | +0,0,0); |
| 3856 | +if (!HeapTupleIsValid(idxtuple)) |
| 3857 | +elog(ERROR,"Cache lookup failed for index %u",indexOid); |
| 3858 | +idxForm= (Form_pg_index)GETSTRUCT(idxtuple); |
| 3859 | +/* |
| 3860 | + * Unset the bit if set. We know it's wrong because we checked |
| 3861 | + * this earlier. |
| 3862 | + */ |
| 3863 | +if (idxForm->indisclustered) |
| 3864 | +{ |
| 3865 | +idxForm->indisclustered= false; |
| 3866 | +simple_heap_update(pg_index,&idxtuple->t_self,idxtuple); |
| 3867 | +CatalogUpdateIndexes(pg_index,idxtuple); |
| 3868 | +} |
| 3869 | +elseif (idxForm->indexrelid==indexForm->indexrelid) |
| 3870 | +{ |
| 3871 | +idxForm->indisclustered= true; |
| 3872 | +simple_heap_update(pg_index,&idxtuple->t_self,idxtuple); |
| 3873 | +CatalogUpdateIndexes(pg_index,idxtuple); |
| 3874 | +} |
| 3875 | +heap_freetuple(idxtuple); |
| 3876 | +} |
| 3877 | +ReleaseSysCache(indexTuple); |
| 3878 | +heap_close(rel,AccessExclusiveLock); |
| 3879 | +heap_close(pg_index,RowExclusiveLock); |
| 3880 | +} |
| 3881 | + |
3798 | 3882 | /*
|
3799 | 3883 | * ALTER TABLE CREATE TOAST TABLE
|
3800 | 3884 | */
|
|