aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c86
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