|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.68 2003/03/20 03:34:55 momjian Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.69 2003/03/20 18: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(Oid relOid, const char *indexName) |
| 3805 | +{ |
| 3806 | + Relation rel, |
| 3807 | + pg_index; |
| 3808 | + List *index; |
| 3809 | + Oid indexOid; |
| 3810 | + HeapTuple indexTuple; |
| 3811 | + Form_pg_index indexForm; |
| 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 | + HeapTuple idxtuple; |
| 3850 | + Form_pg_index idxForm; |
| 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 | + else if (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 | */
|
|
0 commit comments