1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-06 13:46:51 +03:00

Add ALTER TABLE <tablename> CLUSTER ON <indexname>

Alvaro Herrera
This commit is contained in:
Bruce Momjian
2003-03-20 18:52:48 +00:00
parent db5d7ccac9
commit 432b9b0f75
8 changed files with 146 additions and 6 deletions

View File

@@ -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 $
*
*-------------------------------------------------------------------------
*/
@@ -3795,6 +3795,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
*/

View File

@@ -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:

View File

@@ -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),