OSDN Git Service

Add ALTER TABLE <tablename> CLUSTER ON <indexname>
authorBruce Momjian <bruce@momjian.us>
Thu, 20 Mar 2003 18:52:48 +0000 (18:52 +0000)
committerBruce Momjian <bruce@momjian.us>
Thu, 20 Mar 2003 18:52:48 +0000 (18:52 +0000)
Alvaro Herrera

doc/src/sgml/ref/alter_table.sgml
src/backend/commands/tablecmds.c
src/backend/parser/gram.y
src/backend/tcop/utility.c
src/include/commands/tablecmds.h
src/include/nodes/parsenodes.h
src/test/regress/expected/cluster.out
src/test/regress/sql/cluster.sql

index 2b08445..06c9653 100644 (file)
@@ -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">
@@ -139,6 +141,15 @@ ALTER TABLE <replaceable class="PARAMETER">table</replaceable>
      </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>
        <para>
@@ -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>
index f23c88f..3b6a83e 100644 (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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -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
index 1fa5d95..dc8b06e 100644 (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:
index 4d53363..390adeb 100644 (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),
index 6b533ca..a87dbdf 100644 (file)
@@ -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);
index b215f8a..49887f4 100644 (file)
@@ -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
                                                                 *------------
                                                                 */
index d6cc4c9..3e987f8 100644 (file)
@@ -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);
index 57b80ba..06a1441 100644 (file)
@@ -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);