diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/commands/tablecmds.c | 86 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 11 | ||||
-rw-r--r-- | src/backend/tcop/utility.c | 5 |
3 files changed, 99 insertions, 3 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 diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 1fa5d957983..dc8b06e7507 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.407 2003/03/20 07:02:08 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.408 2003/03/20 18:52:47 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -1217,6 +1217,15 @@ AlterTableStmt: n->name = $6; $$ = (Node *)n; } + /* ALTER TABLE <name> CLUSTER ON <indexname> */ + | ALTER TABLE qualified_name CLUSTER ON name + { + AlterTableStmt *n = makeNode(AlterTableStmt); + n->subtype = 'L'; + n->relation = $3; + n->name = $6; + $$ = (Node *)n; + } ; alter_column_default: diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 4d533633d62..390adeb9cb9 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.196 2003/03/20 07:02:11 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.197 2003/03/20 18:52:48 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -609,6 +609,9 @@ ProcessUtility(Node *parsetree, AlterTableOwner(relid, get_usesysid(stmt->name)); break; + case 'L': /* CLUSTER ON */ + AlterTableClusterOn(relid, stmt->name); + break; case 'o': /* ADD OIDS */ AlterTableAlterOids(relid, interpretInhOption(stmt->relation->inhOpt), |