diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index 31f5d1478795b3208a4c86d32d022e6429de5763..36396f62acec1a32071374e57aa99737f6026210 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.83 2004/07/12 01:22:53 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.84 2004/08/02 04:25:31 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -33,7 +33,10 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PAR
 where <replaceable class="PARAMETER">column_constraint</replaceable> is:
 
 [ CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ]
-{ NOT NULL | NULL | UNIQUE | PRIMARY KEY |
+{ NOT NULL | 
+  NULL | 
+  UNIQUE [ USING INDEX TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ] |
+  PRIMARY KEY [ USING INDEX TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ] |
   CHECK (<replaceable class="PARAMETER">expression</replaceable>) |
   REFERENCES <replaceable class="PARAMETER">reftable</replaceable> [ ( <replaceable class="PARAMETER">refcolumn</replaceable> ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
     [ ON DELETE <replaceable class="parameter">action</replaceable> ] [ ON UPDATE <replaceable class="parameter">action</replaceable> ] }
@@ -42,8 +45,8 @@ where <replaceable class="PARAMETER">column_constraint</replaceable> is:
 and <replaceable class="PARAMETER">table_constraint</replaceable> is:
 
 [ CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ]
-{ UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) |
-  PRIMARY KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) |
+{ UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) [ USING INDEX TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ] |
+  PRIMARY KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) [ USING INDEX TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ] |
   CHECK ( <replaceable class="PARAMETER">expression</replaceable> ) |
   FOREIGN KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) REFERENCES <replaceable class="PARAMETER">reftable</replaceable> [ ( <replaceable class="PARAMETER">refcolumn</replaceable> [, ... ] ) ]
     [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE <replaceable class="parameter">action</replaceable> ] [ ON UPDATE <replaceable class="parameter">action</replaceable> ] }
@@ -604,6 +607,18 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
     </listitem>
    </varlistentry>
 
+   <varlistentry>
+    <term><literal>USING INDEX TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable></literal></term>
+    <listitem>
+     <para>
+      This clause allows selection of the tablespace in which the index
+      associated with a <literal>UNIQUE</literal> or <literal>PRIMARY
+      KEY</literal> constraint will be created.  If not supplied, the index
+      will be created in the same tablespace as the table.
+     </para>
+    </listitem>
+   </varlistentry>
+
   </variablelist>
  </refsect1>
 
@@ -950,7 +965,7 @@ CREATE TABLE cinemas (
   </refsect2>
 
   <refsect2>
-   <title>TABLESPACE</title>
+   <title>TABLESPACE and USING INDEX TABLESPACE</title>
 
    <para>
     The <productname>PostgreSQL</productname> concept of tablespaces is not
diff --git a/doc/src/sgml/ref/create_tablespace.sgml b/doc/src/sgml/ref/create_tablespace.sgml
index 08ff4e3254bc937cc1674ff433be0d430e518ecd..04b23ca292dfa9d5b2c4ed8ff0fff6e2312dee0f 100644
--- a/doc/src/sgml/ref/create_tablespace.sgml
+++ b/doc/src/sgml/ref/create_tablespace.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_tablespace.sgml,v 1.2 2004/06/25 21:55:50 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_tablespace.sgml,v 1.3 2004/08/02 04:25:37 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -43,7 +43,7 @@ CREATE TABLESPACE <replaceable class="parameter">tablespacename</replaceable> [
    A user with appropriate privileges can pass
    <replaceable class="parameter">tablespacename</> to <command>CREATE
    DATABASE</>, <command>CREATE SCHEMA</>, <command>CREATE TABLE</>,
-   <command>CREATE INDEX</> or <command>CREATE SEQUENCE</> to have the data
+   <command>CREATE INDEX</> or <command>ADD CONSTRAINT</> to have the data
    files for these objects stored within the specified tablespace.
   </para>
  </refsect1>
@@ -133,7 +133,6 @@ CREATE TABLESPACE indexspace OWNER genevieve LOCATION '/data/indexes';
    <member><xref linkend="sql-createschema" endterm="sql-createschema-title"></member>
    <member><xref linkend="sql-createtable" endterm="sql-createtable-title"></member>
    <member><xref linkend="sql-createindex" endterm="sql-createindex-title"></member>
-   <member><xref linkend="sql-createsequence" endterm="sql-createsequence-title"></member>
    <member><xref linkend="sql-droptablespace" endterm="sql-droptablespace-title"></member>
    <member><xref linkend="sql-altertablespace" endterm="sql-altertablespace-title"></member>
   </simplelist>
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 8c550f4911868141c86f0f4338386c56407f1c8c..3d953dec18c3716a7bad7df90e111138f2a71355 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.288 2004/07/12 05:37:21 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.289 2004/08/02 04:26:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1485,6 +1485,7 @@ _copyConstraint(Constraint *from)
 	COPY_NODE_FIELD(raw_expr);
 	COPY_STRING_FIELD(cooked_expr);
 	COPY_NODE_FIELD(keys);
+	COPY_STRING_FIELD(indexspace);
 
 	return newnode;
 }
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index e2d4d16c782f3c512dd43e75da84368a0b5e1ca4..436b5832815300401efe91591c54c581d8774fa7 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -18,7 +18,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.227 2004/07/12 05:37:24 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.228 2004/08/02 04:26:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1611,6 +1611,7 @@ _equalConstraint(Constraint *a, Constraint *b)
 	COMPARE_NODE_FIELD(raw_expr);
 	COMPARE_STRING_FIELD(cooked_expr);
 	COMPARE_NODE_FIELD(keys);
+	COMPARE_STRING_FIELD(indexspace);
 
 	return true;
 }
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 087ebb39a159cb977842931ba15ba7cb4e72c596..ff6e211a4971c04abdab781d90320a744a2f544e 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.240 2004/06/18 06:13:28 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.241 2004/08/02 04:26:05 tgl Exp $
  *
  * NOTES
  *	  Every node type that can appear in stored rules' parsetrees *must*
@@ -1537,6 +1537,13 @@ _outConstraint(StringInfo str, Constraint *node)
 		case CONSTR_PRIMARY:
 			appendStringInfo(str, "PRIMARY_KEY");
 			WRITE_NODE_FIELD(keys);
+			WRITE_STRING_FIELD(indexspace);
+			break;
+
+		case CONSTR_UNIQUE:
+			appendStringInfo(str, "UNIQUE");
+			WRITE_NODE_FIELD(keys);
+			WRITE_STRING_FIELD(indexspace);
 			break;
 
 		case CONSTR_CHECK:
@@ -1555,11 +1562,6 @@ _outConstraint(StringInfo str, Constraint *node)
 			appendStringInfo(str, "NOT_NULL");
 			break;
 
-		case CONSTR_UNIQUE:
-			appendStringInfo(str, "UNIQUE");
-			WRITE_NODE_FIELD(keys);
-			break;
-
 		default:
 			appendStringInfo(str, "<unrecognized_constraint>");
 			break;
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 1c7be76e72993780696ead273f3ef28e90583884..746975f90b4377c196f1b81f9fec268e1473ab1c 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *	$PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.307 2004/07/12 05:37:44 tgl Exp $
+ *	$PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.308 2004/08/02 04:26:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1199,7 +1199,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
 
 		index->relation = cxt->relation;
 		index->accessMethod = DEFAULT_INDEX_TYPE;
-		index->tableSpace = NULL;
+		index->tableSpace = constraint->indexspace;
 		index->indexParams = NIL;
 		index->whereClause = NULL;
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 1c7faa2c99d0c82ed64457495e0b09aa278625f7..eddfb6e80d276c52cb8e8b5e501a8a32253699df 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.468 2004/07/27 05:10:55 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.469 2004/08/02 04:26:35 tgl Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -320,7 +320,7 @@ static void doNegateFloat(Value *v);
 
 %type <list>	constraints_set_list
 %type <boolean> constraints_set_mode
-%type <str>		OptTableSpace OptTableSpaceOwner
+%type <str>		OptTableSpace OptConsTableSpace OptTableSpaceOwner
 
 
 /*
@@ -1609,6 +1609,7 @@ ColConstraintElem:
 					n->raw_expr = NULL;
 					n->cooked_expr = NULL;
 					n->keys = NULL;
+					n->indexspace = NULL;
 					$$ = (Node *)n;
 				}
 			| NULL_P
@@ -1619,9 +1620,10 @@ ColConstraintElem:
 					n->raw_expr = NULL;
 					n->cooked_expr = NULL;
 					n->keys = NULL;
+					n->indexspace = NULL;
 					$$ = (Node *)n;
 				}
-			| UNIQUE
+			| UNIQUE OptConsTableSpace
 				{
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_UNIQUE;
@@ -1629,9 +1631,10 @@ ColConstraintElem:
 					n->raw_expr = NULL;
 					n->cooked_expr = NULL;
 					n->keys = NULL;
+					n->indexspace = $2;
 					$$ = (Node *)n;
 				}
-			| PRIMARY KEY
+			| PRIMARY KEY OptConsTableSpace
 				{
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_PRIMARY;
@@ -1639,6 +1642,7 @@ ColConstraintElem:
 					n->raw_expr = NULL;
 					n->cooked_expr = NULL;
 					n->keys = NULL;
+					n->indexspace = $3;
 					$$ = (Node *)n;
 				}
 			| CHECK '(' a_expr ')'
@@ -1649,6 +1653,7 @@ ColConstraintElem:
 					n->raw_expr = $3;
 					n->cooked_expr = NULL;
 					n->keys = NULL;
+					n->indexspace = NULL;
 					$$ = (Node *)n;
 				}
 			| DEFAULT b_expr
@@ -1667,6 +1672,7 @@ ColConstraintElem:
 					}
 					n->cooked_expr = NULL;
 					n->keys = NULL;
+					n->indexspace = NULL;
 					$$ = (Node *)n;
 				}
 			| REFERENCES qualified_name opt_column_list key_match key_actions
@@ -1787,9 +1793,10 @@ ConstraintElem:
 					n->name = NULL;
 					n->raw_expr = $3;
 					n->cooked_expr = NULL;
+					n->indexspace = NULL;
 					$$ = (Node *)n;
 				}
-			| UNIQUE '(' columnList ')'
+			| UNIQUE '(' columnList ')' OptConsTableSpace
 				{
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_UNIQUE;
@@ -1797,9 +1804,10 @@ ConstraintElem:
 					n->raw_expr = NULL;
 					n->cooked_expr = NULL;
 					n->keys = $3;
+					n->indexspace = $5;
 					$$ = (Node *)n;
 				}
-			| PRIMARY KEY '(' columnList ')'
+			| PRIMARY KEY '(' columnList ')' OptConsTableSpace
 				{
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_PRIMARY;
@@ -1807,6 +1815,7 @@ ConstraintElem:
 					n->raw_expr = NULL;
 					n->cooked_expr = NULL;
 					n->keys = $4;
+					n->indexspace = $6;
 					$$ = (Node *)n;
 				}
 			| FOREIGN KEY '(' columnList ')' REFERENCES qualified_name
@@ -1916,6 +1925,10 @@ OptTableSpace:   TABLESPACE name					{ $$ = $2; }
 			| /*EMPTY*/								{ $$ = NULL; }
 		;
 
+OptConsTableSpace:   USING INDEX TABLESPACE name	{ $$ = $4; }
+			| /*EMPTY*/								{ $$ = NULL; }
+		;
+
 
 /*
  * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 17ff48400e71c1d6ec8e60e5391976c5ecfa07af..e3b9a4e068a9f62f127d93131e166bbc256e4094 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -3,7 +3,7 @@
  *				back to source text
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.175 2004/07/06 04:50:21 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.176 2004/08/02 04:27:15 tgl Exp $
  *
  *	  This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -162,6 +162,7 @@ static char *pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
 										 int prettyFlags);
 static char *pg_get_expr_worker(text *expr, Oid relid, char *relname,
 								int prettyFlags);
+static Oid get_constraint_index(Oid constraintRelOid, Oid constraintOid);
 static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
 			 int prettyFlags);
 static void make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
@@ -1015,6 +1016,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
 			{
 				Datum		val;
 				bool		isnull;
+				Oid			indexOid;
 
 				/* Start off the constraint definition */
 				if (conForm->contype == CONSTRAINT_PRIMARY)
@@ -1033,6 +1035,29 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
 
 				appendStringInfo(&buf, ")");
 
+				/* Add TABLESPACE if it's not default */
+				indexOid = get_constraint_index(RelationGetRelid(conDesc),
+												constraintId);
+				if (OidIsValid(indexOid))
+				{
+					Oid		reltablespace;
+					Oid		indtablespace;
+
+					reltablespace = get_rel_tablespace(conForm->conrelid);
+					indtablespace = get_rel_tablespace(indexOid);
+					if (OidIsValid(indtablespace) &&
+						indtablespace != reltablespace)
+					{
+						char	*spcname = get_tablespace_name(indtablespace);
+
+						if (spcname)		/* just paranoia... */
+						{
+							appendStringInfo(&buf, " USING INDEX TABLESPACE %s",
+											 quote_identifier(spcname));
+							pfree(spcname);
+						}
+					}
+				}
 				break;
 			}
 		case CONSTRAINT_CHECK:
@@ -1343,6 +1368,67 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS)
 	PG_RETURN_NULL();
 }
 
+/*
+ * get_constraint_index
+ *		Given the OID of a unique or primary-key constraint,
+ *		look up the OID of the underlying index.
+ *
+ * We make the caller pass in the OID of pg_constraint, too, simply because
+ * it's probably got it at hand already.
+ *
+ * Returns InvalidOid if index can't be found.
+ */
+static Oid
+get_constraint_index(Oid constraintRelOid, Oid constraintOid)
+{
+	Oid			result = InvalidOid;
+	Relation	depRel;
+	ScanKeyData key[3];
+	SysScanDesc scan;
+	HeapTuple	tup;
+
+	/* Search the dependency table for the dependent index */
+	depRel = heap_openr(DependRelationName, AccessShareLock);
+
+	ScanKeyInit(&key[0],
+				Anum_pg_depend_refclassid,
+				BTEqualStrategyNumber, F_OIDEQ,
+				ObjectIdGetDatum(constraintRelOid));
+	ScanKeyInit(&key[1],
+				Anum_pg_depend_refobjid,
+				BTEqualStrategyNumber, F_OIDEQ,
+				ObjectIdGetDatum(constraintOid));
+	ScanKeyInit(&key[2],
+				Anum_pg_depend_refobjsubid,
+				BTEqualStrategyNumber, F_INT4EQ,
+				Int32GetDatum(0));
+
+	scan = systable_beginscan(depRel, DependReferenceIndex, true,
+							  SnapshotNow, 3, key);
+
+	while (HeapTupleIsValid(tup = systable_getnext(scan)))
+	{
+		Form_pg_depend	deprec = (Form_pg_depend) GETSTRUCT(tup);
+
+		/*
+		 * We assume any internal dependency of a relation on the constraint
+		 * must be what we are looking for.
+		 */
+		if (deprec->classid == RelOid_pg_class &&
+			deprec->objsubid == 0 &&
+			deprec->deptype == DEPENDENCY_INTERNAL)
+		{
+			result = deprec->objid;
+			break;
+		}
+	}
+
+	systable_endscan(scan);
+	heap_close(depRel, AccessShareLock);
+
+	return result;
+}
+
 
 /* ----------
  * deparse_expression			- General utility for deparsing expressions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index f1b89791e62ed4a958aee0da4f10f4d49809365c..8ffc1522bebe849117caf94fccc6b3faa210cb5f 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -12,7 +12,7 @@
  *	by PostgreSQL
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.380 2004/07/19 21:39:48 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.381 2004/08/02 04:28:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2696,7 +2696,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
 				i_contype,
 				i_conname,
 				i_contableoid,
-				i_conoid;
+				i_conoid,
+				i_tablespace;
 	int			ntups;
 
 	for (i = 0; i < numTables; i++)
@@ -2725,7 +2726,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
 		 * one internal dependency.
 		 */
 		resetPQExpBuffer(query);
-		if (g_fout->remoteVersion >= 70300)
+		if (g_fout->remoteVersion >= 70500)
 		{
 			appendPQExpBuffer(query,
 							  "SELECT t.tableoid, t.oid, "
@@ -2735,7 +2736,33 @@ getIndexes(TableInfo tblinfo[], int numTables)
 							  "i.indkey, i.indisclustered, "
 							  "c.contype, c.conname, "
 							  "c.tableoid as contableoid, "
-							  "c.oid as conoid "
+							  "c.oid as conoid, "
+				  "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) as tablespace "
+							  "FROM pg_catalog.pg_index i "
+				  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
+							  "LEFT JOIN pg_catalog.pg_depend d "
+							  "ON (d.classid = t.tableoid "
+							  "AND d.objid = t.oid "
+							  "AND d.deptype = 'i') "
+							  "LEFT JOIN pg_catalog.pg_constraint c "
+							  "ON (d.refclassid = c.tableoid "
+							  "AND d.refobjid = c.oid) "
+							  "WHERE i.indrelid = '%u'::pg_catalog.oid "
+							  "ORDER BY indexname",
+							  tbinfo->dobj.catId.oid);
+		}
+		else if (g_fout->remoteVersion >= 70300)
+		{
+			appendPQExpBuffer(query,
+							  "SELECT t.tableoid, t.oid, "
+							  "t.relname as indexname, "
+				 "pg_catalog.pg_get_indexdef(i.indexrelid) as indexdef, "
+							  "t.relnatts as indnkeys, "
+							  "i.indkey, i.indisclustered, "
+							  "c.contype, c.conname, "
+							  "c.tableoid as contableoid, "
+							  "c.oid as conoid, "
+							  "NULL as tablespace "
 							  "FROM pg_catalog.pg_index i "
 				  "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
 							  "LEFT JOIN pg_catalog.pg_depend d "
@@ -2761,7 +2788,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
 							  "ELSE '0'::char END as contype, "
 							  "t.relname as conname, "
 							  "0::oid as contableoid, "
-							  "t.oid as conoid "
+							  "t.oid as conoid, "
+							  "NULL as tablespace "
 							  "FROM pg_index i, pg_class t "
 							  "WHERE t.oid = i.indexrelid "
 							  "AND i.indrelid = '%u'::oid "
@@ -2782,7 +2810,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
 							  "ELSE '0'::char END as contype, "
 							  "t.relname as conname, "
 							  "0::oid as contableoid, "
-							  "t.oid as conoid "
+							  "t.oid as conoid, "
+							  "NULL as tablespace "
 							  "FROM pg_index i, pg_class t "
 							  "WHERE t.oid = i.indexrelid "
 							  "AND i.indrelid = '%u'::oid "
@@ -2806,6 +2835,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
 		i_conname = PQfnumber(res, "conname");
 		i_contableoid = PQfnumber(res, "contableoid");
 		i_conoid = PQfnumber(res, "conoid");
+		i_tablespace = PQfnumber(res, "tablespace");
 
 		indxinfo = (IndxInfo *) malloc(ntups * sizeof(IndxInfo));
 		constrinfo = (ConstraintInfo *) malloc(ntups * sizeof(ConstraintInfo));
@@ -2823,6 +2853,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
 			indxinfo[j].indextable = tbinfo;
 			indxinfo[j].indexdef = strdup(PQgetvalue(res, j, i_indexdef));
 			indxinfo[j].indnkeys = atoi(PQgetvalue(res, j, i_indnkeys));
+			indxinfo[j].tablespace = strdup(PQgetvalue(res, j, i_tablespace));
 
 			/*
 			 * In pre-7.4 releases, indkeys may contain more entries than
@@ -6910,7 +6941,18 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
 							  fmtId(attname));
 		}
 
-		appendPQExpBuffer(q, ");\n");
+		appendPQExpBuffer(q, ")");
+
+		/* Output tablespace clause if necessary */
+		if (strlen(indxinfo->tablespace) != 0 &&
+			strcmp(indxinfo->tablespace,
+				   indxinfo->indextable->reltablespace) != 0)
+		{
+			appendPQExpBuffer(q, " USING INDEX TABLESPACE %s",
+							  fmtId(indxinfo->tablespace));
+		}
+
+		appendPQExpBuffer(q, ";\n");
 
 		/* If the index is clustered, we need to record that. */
 		if (indxinfo->indisclustered)
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 55a25212257c13ac0cd728abd755ff404ee36dcb..9c43528bcef4888f56c658c6ff86c06522a2de8f 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.109 2004/06/18 06:14:00 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.110 2004/08/02 04:28:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -238,6 +238,7 @@ typedef struct _indxInfo
 	DumpableObject dobj;
 	TableInfo  *indextable;		/* link to table the index is for */
 	char	   *indexdef;
+	char	   *tablespace;		/* tablespace in which index is stored */
 	int			indnkeys;
 	Oid		   *indkeys;
 	bool		indisclustered;
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 9abfdb86054052fa9722b574e420b2b71b83dc13..a4be20647f21639f4d351a23bb9a6bf502f1a9db 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.263 2004/07/27 05:11:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.264 2004/08/02 04:28:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -992,6 +992,8 @@ typedef struct Constraint
 	char	   *cooked_expr;	/* expr, as nodeToString representation */
 	List	   *keys;			/* String nodes naming referenced
 								 * column(s) */
+	char	   *indexspace;		/* index tablespace for PKEY/UNIQUE
+								 * constraints; NULL for default */
 } Constraint;
 
 /* ----------