mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
Add ALTER TABLE <tablename> CLUSTER ON <indexname>
Alvaro Herrera
This commit is contained in:
parent
db5d7ccac9
commit
432b9b0f75
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.56 2003/02/19 04:06:28 momjian Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.57 2003/03/20 18:52:47 momjian Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -46,6 +46,8 @@ ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ * ]
|
||||
DROP CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ]
|
||||
ALTER TABLE <replaceable class="PARAMETER">table</replaceable>
|
||||
OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
|
||||
ALTER TABLE <replaceable class="PARAMETER">table</replaceable>
|
||||
CLUSTER ON <replaceable class="PARAMETER">index_name</replaceable>
|
||||
</synopsis>
|
||||
|
||||
<refsect2 id="R2-SQL-ALTERTABLE-1">
|
||||
@ -138,6 +140,15 @@ ALTER TABLE <replaceable class="PARAMETER">table</replaceable>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable class="PARAMETER"> index_name </replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The index name on which the table should be marked for clustering.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>CASCADE</term>
|
||||
<listitem>
|
||||
@ -344,6 +355,16 @@ ALTER TABLE <replaceable class="PARAMETER">table</replaceable>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>CLUSTER</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This form marks a table for future <xref linkend="SQL-CLUSTER" endterm="sql-cluster-title">
|
||||
operations.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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:
|
||||
|
@ -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),
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: tablecmds.h,v 1.11 2003/02/13 05:20:03 momjian Exp $
|
||||
* $Id: tablecmds.h,v 1.12 2003/03/20 18:52:48 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -43,6 +43,8 @@ extern void AlterTableDropConstraint(Oid myrelid, bool recurse,
|
||||
const char *constrName,
|
||||
DropBehavior behavior);
|
||||
|
||||
extern void AlterTableClusterOn(Oid relOid, const char *indexName);
|
||||
|
||||
extern void AlterTableCreateToastTable(Oid relOid, bool silent);
|
||||
|
||||
extern void AlterTableOwner(Oid relationOid, int32 newOwnerSysId);
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: parsenodes.h,v 1.234 2003/03/20 07:02:11 momjian Exp $
|
||||
* $Id: parsenodes.h,v 1.235 2003/03/20 18:52:48 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -704,6 +704,7 @@ typedef struct AlterTableStmt
|
||||
* X = drop constraint
|
||||
* E = create toast table
|
||||
* U = change owner
|
||||
* L = CLUSTER ON
|
||||
* o = DROP OIDS
|
||||
*------------
|
||||
*/
|
||||
|
@ -285,6 +285,18 @@ WHERE pg_class.oid=indexrelid
|
||||
clstr_tst_c
|
||||
(1 row)
|
||||
|
||||
-- Try changing indisclustered
|
||||
ALTER TABLE clstr_tst CLUSTER ON clstr_tst_b_c;
|
||||
SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2
|
||||
WHERE pg_class.oid=indexrelid
|
||||
AND indrelid=pg_class_2.oid
|
||||
AND pg_class_2.relname = 'clstr_tst'
|
||||
AND indisclustered;
|
||||
relname
|
||||
---------------
|
||||
clstr_tst_b_c
|
||||
(1 row)
|
||||
|
||||
-- Verify that clustering all tables does in fact cluster the right ones
|
||||
CREATE USER clstr_user;
|
||||
CREATE TABLE clstr_1 (a INT PRIMARY KEY);
|
||||
|
@ -87,6 +87,14 @@ WHERE pg_class.oid=indexrelid
|
||||
AND pg_class_2.relname = 'clstr_tst'
|
||||
AND indisclustered;
|
||||
|
||||
-- Try changing indisclustered
|
||||
ALTER TABLE clstr_tst CLUSTER ON clstr_tst_b_c;
|
||||
SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2
|
||||
WHERE pg_class.oid=indexrelid
|
||||
AND indrelid=pg_class_2.oid
|
||||
AND pg_class_2.relname = 'clstr_tst'
|
||||
AND indisclustered;
|
||||
|
||||
-- Verify that clustering all tables does in fact cluster the right ones
|
||||
CREATE USER clstr_user;
|
||||
CREATE TABLE clstr_1 (a INT PRIMARY KEY);
|
||||
|
Loading…
Reference in New Issue
Block a user