From 09d4e96d7e957ae34263650498b279452fe95265 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Fri, 20 Aug 2004 04:29:33 +0000
Subject: [PATCH] Add ALTER INDEX, particularly for moving tablespaces.

Gavin Sherry
---
 doc/src/sgml/ref/alter_index.sgml | 188 ++++++++++++++++++++++++++++++
 src/backend/parser/gram.y         |  58 ++++++---
 src/backend/tcop/utility.c        |  21 +++-
 src/bin/psql/tab-complete.c       |  15 ++-
 src/include/nodes/parsenodes.h    |   3 +-
 5 files changed, 266 insertions(+), 19 deletions(-)
 create mode 100644 doc/src/sgml/ref/alter_index.sgml

diff --git a/doc/src/sgml/ref/alter_index.sgml b/doc/src/sgml/ref/alter_index.sgml
new file mode 100644
index 00000000000..3eaf0f7291f
--- /dev/null
+++ b/doc/src/sgml/ref/alter_index.sgml
@@ -0,0 +1,188 @@
+<!--
+$PostgreSQL: pgsql/doc/src/sgml/ref/alter_index.sgml,v 1.1 2004/08/20 04:29:32 momjian Exp $
+PostgreSQL documentation
+-->
+
+<refentry id="SQL-ALTERINDEX">
+ <refmeta>
+  <refentrytitle id="sql-alterindex-title">ALTER INDEX</refentrytitle>
+  <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+  <refname>ALTER INDEX</refname>
+  <refpurpose>change the definition of an index</refpurpose>
+ </refnamediv>
+
+ <indexterm zone="sql-alterindex">
+  <primary>ALTER INDEX</primary>
+ </indexterm>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER INDEX <replaceable class="PARAMETER">name</replaceable> 
+    <replaceable class="PARAMETER">action</replaceable> [, ... ]
+ALTER INDEX <replaceable class="PARAMETER">name</replaceable>
+    RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
+
+where <replaceable class="PARAMETER">action</replaceable> is one of:
+
+    OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
+    SET INDEXSPACE <replaceable class="PARAMETER">indexspace_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+  <title>Description</title>
+
+  <para>
+   <command>ALTER INDEX</command> changes the definition of an existing index.
+   There are several subforms:
+
+  <variablelist>
+
+   <varlistentry>
+    <term><literal>OWNER</literal></term>
+    <listitem>
+     <para>
+      This form changes the owner of the index to the
+      specified user.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term><literal>SET TABLESPACE</literal></term>
+    <listitem>
+     <para>
+      This form changes the index's tablespace to the specified tablespace and
+      moves the data file(s) associated with the index to the new tablespace.
+      See also 
+      <xref linkend="SQL-CREATETABLESPACE" endterm="sql-createtablespace-title">.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term><literal>RENAME</literal></term>
+    <listitem>
+     <para>
+      The <literal>RENAME</literal> forms change the name of the index. 
+	  There is no effect on the stored data.
+     </para>
+    </listitem>
+   </varlistentry>
+
+  </variablelist>
+  </para>
+
+  <para>
+   All the actions except <literal>RENAME</literal> can be combined into
+   a list of multiple alterations to apply in parallel.
+  </para>
+
+ </refsect1>
+
+ <refsect1>
+  <title>Parameters</title>
+
+    <variablelist>
+
+     <varlistentry>
+      <term><replaceable class="PARAMETER">name</replaceable></term>
+      <listitem>
+       <para>
+	The name (possibly schema-qualified) of an existing index to
+	alter.
+       </para>
+      </listitem>
+     </varlistentry>
+
+
+     <varlistentry>
+      <term><replaceable class="PARAMETER">new_name</replaceable></term>
+      <listitem>
+       <para>
+	New name for the index.
+       </para>
+      </listitem>
+     </varlistentry>
+
+
+     <varlistentry>
+      <term><replaceable class="PARAMETER">new_owner</replaceable></term>
+      <listitem>
+       <para>
+	The user name of the new owner of the index.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><replaceable class="PARAMETER">tablespace_name</replaceable></term>
+      <listitem>
+       <para>
+	The tablespace name to which the index will be moved.
+       </para>
+      </listitem>
+     </varlistentry>
+
+    </variablelist>
+ </refsect1>
+
+ <refsect1>
+  <title>Notes</title>
+
+   <para>
+	This same operations are supported by <literal>ALTER TABLE</>. See also
+	<xref linkend="SQL-ALTERTABLE" endterm="SQL-ALTERTABLE-TITLE">.
+   </para>
+
+   <para>
+    Changing any part of a system catalog index is not permitted.
+   </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Examples</title>
+  <para>
+   To rename an existing index:
+<programlisting>
+ALTER INDEX distributors RENAME TO suppliers;
+</programlisting>
+  </para>
+
+  <para> 
+	To move a index to a different tablespace:
+<programlisting>
+ALTER INDEX distributors SET TABLESPACE fasttablespace;
+</programlisting>
+  </para>
+
+ </refsect1>
+
+ <refsect1>
+  <title>Compatibility</title>
+
+  <para>
+	<literal>ALTER INDEX</> is a PostgreSQL extension.
+  </para>
+ </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"../reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:"/usr/lib/sgml/catalog"
+sgml-local-ecat-files:nil
+End:
+-->
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index e8bc3cf5ade..5240a69dd23 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.471 2004/08/12 21:00:28 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.472 2004/08/20 04:29:32 momjian Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -156,8 +156,8 @@ static void doNegateFloat(Value *v);
 %type <node>	alter_column_default opclass_item alter_using
 %type <ival>	add_drop
 
-%type <node>	alter_table_cmd
-%type <list>	alter_table_cmds
+%type <node>	alter_table_cmd alter_rel_cmd
+%type <list>	alter_table_cmds alter_rel_cmds
 
 %type <dbehavior>	opt_drop_behavior
 
@@ -1138,7 +1138,7 @@ CheckPointStmt:
 
 /*****************************************************************************
  *
- *	ALTER TABLE variations
+ *	ALTER [ TABLE | INDEX ] variations
  *
  *****************************************************************************/
 
@@ -1148,6 +1148,15 @@ AlterTableStmt:
 					AlterTableStmt *n = makeNode(AlterTableStmt);
 					n->relation = $3;
 					n->cmds = $4;
+					n->relkind = OBJECT_TABLE; 
+					$$ = (Node *)n;
+				}
+		|	ALTER INDEX relation_expr alter_rel_cmds
+				{
+					AlterTableStmt *n = makeNode(AlterTableStmt);
+					n->relation = $3;
+					n->cmds = $4;
+					n->relkind = OBJECT_INDEX;
 					$$ = (Node *)n;
 				}
 		;
@@ -1262,14 +1271,6 @@ alter_table_cmd:
 					n->subtype = AT_ToastTable;
 					$$ = (Node *)n;
 				}
-			/* ALTER TABLE <name> OWNER TO UserId */
-			|  OWNER TO UserId
-				{
-					AlterTableCmd *n = makeNode(AlterTableCmd);
-					n->subtype = AT_ChangeOwner;
-					n->name = $3;
-					$$ = (Node *)n;
-				}
 			/* ALTER TABLE <name> CLUSTER ON <indexname> */
 			| CLUSTER ON name
 				{
@@ -1286,7 +1287,27 @@ alter_table_cmd:
 					n->name = NULL;
 					$$ = (Node *)n;
 				}
-			/* ALTER TABLE <name> SET TABLESPACE <tablespacename> */
+			| alter_rel_cmd
+				{
+					$$ = $1;
+				}
+		;
+
+alter_rel_cmds: alter_rel_cmd                         { $$ = list_make1($1); }
+            | alter_rel_cmds ',' alter_rel_cmd  { $$ = lappend($1, $3); }
+        ;
+
+
+alter_rel_cmd:
+			/* ALTER [ TABLE | INDEX ] <name> OWNER TO UserId */
+			OWNER TO UserId
+				{
+					AlterTableCmd *n = makeNode(AlterTableCmd);
+					n->subtype = AT_ChangeOwner;
+					n->name = $3;
+					$$ = (Node *)n;
+				}
+			/* ALTER [ TABLE | INDEX ] <name> SET TABLESPACE <tablespacename> */
 			| SET TABLESPACE name
 				{
 					AlterTableCmd *n = makeNode(AlterTableCmd);
@@ -1319,6 +1340,8 @@ alter_using:
 			| /* EMPTY */				{ $$ = NULL; }
 		;
 
+
+
 /*****************************************************************************
  *
  *		QUERY :
@@ -3660,6 +3683,15 @@ RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name
 					n->newname = $6;
 					$$ = (Node *)n;
 				}
+			| ALTER INDEX relation_expr RENAME TO name
+				{
+					RenameStmt *n = makeNode(RenameStmt);
+					n->renameType = OBJECT_INDEX;
+					n->relation = $3;
+					n->subname = NULL;
+					n->newname = $6;
+					$$ = (Node *)n;
+				}
 			| ALTER TABLE relation_expr RENAME opt_column name TO name
 				{
 					RenameStmt *n = makeNode(RenameStmt);
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 0fff253a61c..b8c853c0f34 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.225 2004/08/12 21:00:34 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.226 2004/08/20 04:29:32 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1269,6 +1269,9 @@ CreateCommandTag(Node *parsetree)
 				case OBJECT_GROUP:
 					tag = "ALTER GROUP";
 					break;
+				case OBJECT_INDEX:
+					tag = "ALTER INDEX";
+					break;
 				case OBJECT_LANGUAGE:
 					tag = "ALTER LANGUAGE";
 					break;
@@ -1331,9 +1334,21 @@ CreateCommandTag(Node *parsetree)
 			break;
 
 		case T_AlterTableStmt:
-			tag = "ALTER TABLE";
-			break;
+			{
+				AlterTableStmt *stmt = (AlterTableStmt *) parsetree;
+
+				/* 
+				 * We might be supporting ALTER INDEX here, so
+				 * set the completion table appropriately.
+				 * Catch all other possibilities with ALTER TABLE
+				 */
 
+				if(stmt->relkind == OBJECT_INDEX) 
+					tag = "ALTER INDEX";
+				else
+					tag = "ALTER TABLE";
+			}
+			break;
 		case T_AlterDomainStmt:
 			tag = "ALTER DOMAIN";
 			break;
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 130fcd33f4b..1b036be8427 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2003, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.109 2004/07/28 14:23:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.110 2004/08/20 04:29:32 momjian Exp $
  */
 
 /*----------------------------------------------------------------------
@@ -632,7 +632,8 @@ psql_completion(char *text, int start, int end)
 			 pg_strcasecmp(prev3_wd, "TABLE") != 0)
 	{
 		static const char *const list_ALTER[] =
-		{"DATABASE", "GROUP", "SCHEMA", "TABLE", "TRIGGER", "USER", NULL};
+		{"DATABASE", "GROUP", "SCHEMA", "TABLE", "TRIGGER", "USER", "INDEX",
+			 NULL};
 
 		COMPLETE_WITH_LIST(list_ALTER);
 	}
@@ -646,6 +647,16 @@ psql_completion(char *text, int start, int end)
 
 		COMPLETE_WITH_LIST(list_ALTERDATABASE);
 	}
+	/* ALTER INDEX <name> */
+	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
+             pg_strcasecmp(prev2_wd, "INDEX") == 0)
+    {
+        static const char *const list_ALTERINDEX[] =
+        {"SET TABLESPACE", "OWNER TO", "RENAME TO", NULL};
+                                                                                
+        COMPLETE_WITH_LIST(list_ALTERINDEX);
+    }
+
 	/* ALTER TRIGGER <name>, add ON */
 	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
 			 pg_strcasecmp(prev2_wd, "TRIGGER") == 0)
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index aff28bea08f..862b2572d91 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.266 2004/08/19 20:57:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.267 2004/08/20 04:29:33 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -797,6 +797,7 @@ typedef struct AlterTableStmt
 	NodeTag		type;
 	RangeVar   *relation;		/* table to work on */
 	List	   *cmds;			/* list of subcommands */
+	ObjectType	relkind;		/* type of object */
 } AlterTableStmt;
 
 typedef enum AlterTableType
-- 
GitLab