diff options
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r-- | src/backend/commands/tablecmds.c | 86 |
1 files changed, 85 insertions, 1 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index f23c88f6fe6..3b6a83e165b 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.68 2003/03/20 03:34:55 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.69 2003/03/20 18:52:47 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -3796,6 +3796,90 @@ CheckTupleType(Form_pg_class tuple_class) } /* + * ALTER TABLE CLUSTER ON + * + * The only thing we have to do is to change the indisclustered bits. + */ +void +AlterTableClusterOn(Oid relOid, const char *indexName) +{ + Relation rel, + pg_index; + List *index; + Oid indexOid; + HeapTuple indexTuple; + Form_pg_index indexForm; + + rel = heap_open(relOid, AccessExclusiveLock); + + indexOid = get_relname_relid(indexName, rel->rd_rel->relnamespace); + + if (!OidIsValid(indexOid)) + elog(ERROR, "ALTER TABLE: cannot find index \"%s\" for table \"%s\"", + indexName, NameStr(rel->rd_rel->relname)); + + indexTuple = SearchSysCache(INDEXRELID, + ObjectIdGetDatum(indexOid), + 0, 0, 0); + + if (!HeapTupleIsValid(indexTuple)) + elog(ERROR, "Cache lookup failed for index %u", + indexOid); + indexForm = (Form_pg_index) GETSTRUCT(indexTuple); + + /* + * If this is the same index the relation was previously + * clustered on, no need to do anything. + */ + if (indexForm->indisclustered) + { + elog(NOTICE, "ALTER TABLE: table \"%s\" is already being clustered on index \"%s\"", + NameStr(rel->rd_rel->relname), indexName); + heap_close(rel, AccessExclusiveLock); + return; + } + + pg_index = heap_openr(IndexRelationName, RowExclusiveLock); + + /* + * Now check each index in the relation and set the bit where needed. + */ + foreach (index, RelationGetIndexList(rel)) + { + HeapTuple idxtuple; + Form_pg_index idxForm; + + indexOid = lfirsto(index); + idxtuple = SearchSysCacheCopy(INDEXRELID, + ObjectIdGetDatum(indexOid), + 0, 0, 0); + if (!HeapTupleIsValid(idxtuple)) + elog(ERROR, "Cache lookup failed for index %u", indexOid); + idxForm = (Form_pg_index) GETSTRUCT(idxtuple); + /* + * Unset the bit if set. We know it's wrong because we checked + * this earlier. + */ + if (idxForm->indisclustered) + { + idxForm->indisclustered = false; + simple_heap_update(pg_index, &idxtuple->t_self, idxtuple); + CatalogUpdateIndexes(pg_index, idxtuple); + } + else if (idxForm->indexrelid == indexForm->indexrelid) + { + idxForm->indisclustered = true; + simple_heap_update(pg_index, &idxtuple->t_self, idxtuple); + CatalogUpdateIndexes(pg_index, idxtuple); + } + heap_freetuple(idxtuple); + } + ReleaseSysCache(indexTuple); + heap_close(rel, AccessExclusiveLock); + heap_close(pg_index, RowExclusiveLock); +} + +/* * ALTER TABLE CREATE TOAST TABLE */ void |