diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml
index e86712e26b5..5d864be510c 100644
--- a/doc/src/sgml/ref/alter_table.sgml
+++ b/doc/src/sgml/ref/alter_table.sgml
@@ -1,5 +1,5 @@
@@ -42,6 +42,7 @@ where action is one of:
SET WITHOUT OIDS
OWNER TO new_owner
CLUSTER ON index_name
+ SET WITHOUT CLUSTER
@@ -213,12 +214,24 @@ where action is one of:
CLUSTER
- This form selects the default controlling index for future
+ This form selects the default index for future
+
operations.
+
+ SET WITHOUT CLUSTER
+
+
+ This form removes the most recently used
+
+ index specification from the table.
+
+
+
+
RENAME
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 431c4ac742a..71f5ad0c001 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.108 2004/05/26 04:41:12 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.109 2004/06/02 21:01:08 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -233,6 +233,7 @@ static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab);
static void ATPostAlterTypeParse(char *cmd, List **wqueue);
static void ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId);
static void ATExecClusterOn(Relation rel, const char *indexName);
+static void ATExecDropCluster(Relation rel);
static int ri_trigger_type(Oid tgfoid);
static void update_ri_trigger_args(Oid relid,
const char *oldname,
@@ -1922,8 +1923,9 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
pass = AT_PASS_MISC;
break;
case AT_ClusterOn: /* CLUSTER ON */
+ case AT_DropCluster: /* SET WITHOUT CLUSTER */
ATSimplePermissions(rel, false);
- /* This command never recurses */
+ /* These commands never recurse */
/* No command-specific prep needed */
pass = AT_PASS_MISC;
break;
@@ -2083,6 +2085,9 @@ ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd)
case AT_ClusterOn: /* CLUSTER ON */
ATExecClusterOn(rel, cmd->name);
break;
+ case AT_DropCluster: /* SET WITHOUT CLUSTER */
+ ATExecDropCluster(rel);
+ break;
case AT_DropOids: /* SET WITHOUT OIDS */
/*
* Nothing to do here; we'll have generated a DropColumn subcommand
@@ -5044,6 +5049,19 @@ ATExecClusterOn(Relation rel, const char *indexName)
mark_index_clustered(rel, indexOid);
}
+/*
+ * ALTER TABLE SET WITHOUT CLUSTER
+ *
+ * We have to find any indexes on the table that have indisclustered bit
+ * set and turn it off.
+ */
+static void
+ATExecDropCluster(Relation rel)
+{
+ mark_index_clustered(rel, InvalidOid);
+}
+
+
/*
* ALTER TABLE CREATE TOAST TABLE
*
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 249c5907709..61a3bd477e6 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.459 2004/06/01 03:28:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.460 2004/06/02 21:01:09 momjian Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -1277,6 +1277,14 @@ alter_table_cmd:
n->name = $3;
$$ = (Node *)n;
}
+ /* ALTER TABLE SET WITHOUT CLUSTER */
+ | SET WITHOUT CLUSTER
+ {
+ AlterTableCmd *n = makeNode(AlterTableCmd);
+ n->subtype = AT_DropCluster;
+ n->name = NULL;
+ $$ = (Node *)n;
+ }
;
alter_column_default:
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 2943d0e9e08..8f6cc25e0aa 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.256 2004/05/26 13:57:02 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.257 2004/06/02 21:01:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -793,6 +793,7 @@ typedef enum AlterTableType
AT_ToastTable, /* create toast table */
AT_ChangeOwner, /* change owner */
AT_ClusterOn, /* CLUSTER ON */
+ AT_DropCluster, /* SET WITHOUT CLUSTER */
AT_DropOids /* SET WITHOUT OIDS */
} AlterTableType;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index b221c6d043b..e5f2e4cda65 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -297,6 +297,17 @@ WHERE pg_class.oid=indexrelid
clstr_tst_b_c
(1 row)
+-- Try turning off all clustering
+ALTER TABLE clstr_tst SET WITHOUT CLUSTER;
+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
+ ---------
+ (0 rows)
+
-- Verify that clustering all tables does in fact cluster the right ones
CREATE USER clstr_user;
CREATE TABLE clstr_1 (a INT PRIMARY KEY);
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 06a1441a04a..f669922b031 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -95,6 +95,14 @@ WHERE pg_class.oid=indexrelid
AND pg_class_2.relname = 'clstr_tst'
AND indisclustered;
+-- Try turning off all clustering
+ALTER TABLE clstr_tst SET WITHOUT CLUSTER;
+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);