diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 7e4afd70bd520d797067c948d386b4bab0a92b96..8b3331702c5dce5ed47ae05a8c702bf1ee4394b5 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.6 2007/11/15 21:14:31 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.7 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,6 +18,7 @@
 #include "access/reloptions.h"
 #include "catalog/pg_type.h"
 #include "commands/defrem.h"
+#include "nodes/makefuncs.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/rel.h"
@@ -149,6 +150,50 @@ transformRelOptions(Datum oldOptions, List *defList,
 }
 
 
+/*
+ * Convert the text-array format of reloptions into a List of DefElem.
+ * This is the inverse of transformRelOptions().
+ */
+List *
+untransformRelOptions(Datum options)
+{
+	List	   *result = NIL;
+	ArrayType  *array;
+	Datum	   *optiondatums;
+	int			noptions;
+	int			i;
+
+	/* Nothing to do if no options */
+	if (options == (Datum) 0)
+		return result;
+
+	array = DatumGetArrayTypeP(options);
+
+	Assert(ARR_ELEMTYPE(array) == TEXTOID);
+
+	deconstruct_array(array, TEXTOID, -1, false, 'i',
+					  &optiondatums, NULL, &noptions);
+
+	for (i = 0; i < noptions; i++)
+	{
+		char	   *s;
+		char	   *p;
+		Node	   *val = NULL;
+
+		s = DatumGetCString(DirectFunctionCall1(textout, optiondatums[i]));
+		p = strchr(s, '=');
+		if (p)
+		{
+			*p++ = '\0';
+			val = (Node *) makeString(pstrdup(p));
+		}
+		result = lappend(result, makeDefElem(pstrdup(s), val));
+	}
+
+	return result;
+}
+
+
 /*
  * Interpret reloptions that are given in text-array format.
  *
diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y
index 3fd29b7e97168894adf42eab40ba47fc28e37242..bd640804c461788e19780aeeabf66664d10deb01 100644
--- a/src/backend/bootstrap/bootparse.y
+++ b/src/backend/bootstrap/bootparse.y
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.89 2007/07/17 05:02:00 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.90 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -252,7 +252,7 @@ Boot_DeclareIndexStmt:
 								LexIDStr($8),
 								NULL,
 								$10,
-								NULL, NIL, NULL,
+								NULL, NIL,
 								false, false, false,
 								false, false, true, false, false);
 					do_end();
@@ -270,7 +270,7 @@ Boot_DeclareUniqueIndexStmt:
 								LexIDStr($9),
 								NULL,
 								$11,
-								NULL, NIL, NULL,
+								NULL, NIL,
 								true, false, false,
 								false, false, true, false, false);
 					do_end();
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
index 3574ab1ba3a3ed3e36153e82e73f4590d5b0d8a7..a35b376cc10db94a051031dff4b88f2b1eb42088 100644
--- a/src/backend/catalog/pg_depend.c
+++ b/src/backend/catalog/pg_depend.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/pg_depend.c,v 1.24 2007/01/05 22:19:25 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/pg_depend.c,v 1.25 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,9 +18,11 @@
 #include "access/heapam.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
+#include "catalog/pg_constraint.h"
 #include "catalog/pg_depend.h"
 #include "miscadmin.h"
 #include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
 
 
 static bool isObjectPinned(const ObjectAddress *object, Relation rel);
@@ -260,6 +262,62 @@ changeDependencyFor(Oid classId, Oid objectId,
 	return count;
 }
 
+/*
+ * isObjectPinned()
+ *
+ * Test if an object is required for basic database functionality.
+ * Caller must already have opened pg_depend.
+ *
+ * The passed subId, if any, is ignored; we assume that only whole objects
+ * are pinned (and that this implies pinning their components).
+ */
+static bool
+isObjectPinned(const ObjectAddress *object, Relation rel)
+{
+	bool		ret = false;
+	SysScanDesc scan;
+	HeapTuple	tup;
+	ScanKeyData key[2];
+
+	ScanKeyInit(&key[0],
+				Anum_pg_depend_refclassid,
+				BTEqualStrategyNumber, F_OIDEQ,
+				ObjectIdGetDatum(object->classId));
+
+	ScanKeyInit(&key[1],
+				Anum_pg_depend_refobjid,
+				BTEqualStrategyNumber, F_OIDEQ,
+				ObjectIdGetDatum(object->objectId));
+
+	scan = systable_beginscan(rel, DependReferenceIndexId, true,
+							  SnapshotNow, 2, key);
+
+	/*
+	 * Since we won't generate additional pg_depend entries for pinned
+	 * objects, there can be at most one entry referencing a pinned object.
+	 * Hence, it's sufficient to look at the first returned tuple; we don't
+	 * need to loop.
+	 */
+	tup = systable_getnext(scan);
+	if (HeapTupleIsValid(tup))
+	{
+		Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
+
+		if (foundDep->deptype == DEPENDENCY_PIN)
+			ret = true;
+	}
+
+	systable_endscan(scan);
+
+	return ret;
+}
+
+
+/*
+ * Various special-purpose lookups and manipulations of pg_depend.
+ */
+
+
 /*
  * Detect whether a sequence is marked as "owned" by a column
  *
@@ -359,52 +417,120 @@ markSequenceUnowned(Oid seqId)
 	heap_close(depRel, RowExclusiveLock);
 }
 
+
 /*
- * isObjectPinned()
- *
- * Test if an object is required for basic database functionality.
- * Caller must already have opened pg_depend.
+ * get_constraint_index
+ *		Given the OID of a unique or primary-key constraint, return the
+ *		OID of the underlying unique index.
  *
- * The passed subId, if any, is ignored; we assume that only whole objects
- * are pinned (and that this implies pinning their components).
+ * Return InvalidOid if the index couldn't be found; this suggests the
+ * given OID is bogus, but we leave it to caller to decide what to do.
  */
-static bool
-isObjectPinned(const ObjectAddress *object, Relation rel)
+Oid
+get_constraint_index(Oid constraintId)
 {
-	bool		ret = false;
+	Oid			indexId = InvalidOid;
+	Relation	depRel;
+	ScanKeyData key[3];
 	SysScanDesc scan;
 	HeapTuple	tup;
-	ScanKeyData key[2];
+
+	/* Search the dependency table for the dependent index */
+	depRel = heap_open(DependRelationId, AccessShareLock);
 
 	ScanKeyInit(&key[0],
 				Anum_pg_depend_refclassid,
 				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(object->classId));
-
+				ObjectIdGetDatum(ConstraintRelationId));
 	ScanKeyInit(&key[1],
 				Anum_pg_depend_refobjid,
 				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(object->objectId));
+				ObjectIdGetDatum(constraintId));
+	ScanKeyInit(&key[2],
+				Anum_pg_depend_refobjsubid,
+				BTEqualStrategyNumber, F_INT4EQ,
+				Int32GetDatum(0));
 
-	scan = systable_beginscan(rel, DependReferenceIndexId, true,
-							  SnapshotNow, 2, key);
+	scan = systable_beginscan(depRel, DependReferenceIndexId, true,
+							  SnapshotNow, 3, key);
 
-	/*
-	 * Since we won't generate additional pg_depend entries for pinned
-	 * objects, there can be at most one entry referencing a pinned object.
-	 * Hence, it's sufficient to look at the first returned tuple; we don't
-	 * need to loop.
-	 */
-	tup = systable_getnext(scan);
-	if (HeapTupleIsValid(tup))
+	while (HeapTupleIsValid(tup = systable_getnext(scan)))
 	{
-		Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
+		Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
 
-		if (foundDep->deptype == DEPENDENCY_PIN)
-			ret = true;
+		/*
+		 * We assume any internal dependency of an index on the constraint
+		 * must be what we are looking for.  (The relkind test is just
+		 * paranoia; there shouldn't be any such dependencies otherwise.)
+		 */
+		if (deprec->classid == RelationRelationId &&
+			deprec->objsubid == 0 &&
+			deprec->deptype == DEPENDENCY_INTERNAL &&
+			get_rel_relkind(deprec->objid) == RELKIND_INDEX)
+		{
+			indexId = deprec->objid;
+			break;
+		}
 	}
 
 	systable_endscan(scan);
+	heap_close(depRel, AccessShareLock);
 
-	return ret;
+	return indexId;
+}
+
+/*
+ * get_index_constraint
+ *		Given the OID of an index, return the OID of the owning unique or
+ *		primary-key constraint, or InvalidOid if no such constraint.
+ */
+Oid
+get_index_constraint(Oid indexId)
+{
+	Oid			constraintId = InvalidOid;
+	Relation	depRel;
+	ScanKeyData key[3];
+	SysScanDesc scan;
+	HeapTuple	tup;
+
+	/* Search the dependency table for the index */
+	depRel = heap_open(DependRelationId, AccessShareLock);
+
+	ScanKeyInit(&key[0],
+				Anum_pg_depend_classid,
+				BTEqualStrategyNumber, F_OIDEQ,
+				ObjectIdGetDatum(RelationRelationId));
+	ScanKeyInit(&key[1],
+				Anum_pg_depend_objid,
+				BTEqualStrategyNumber, F_OIDEQ,
+				ObjectIdGetDatum(indexId));
+	ScanKeyInit(&key[2],
+				Anum_pg_depend_objsubid,
+				BTEqualStrategyNumber, F_INT4EQ,
+				Int32GetDatum(0));
+
+	scan = systable_beginscan(depRel, DependDependerIndexId, true,
+							  SnapshotNow, 3, key);
+
+	while (HeapTupleIsValid(tup = systable_getnext(scan)))
+	{
+		Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
+
+		/*
+		 * We assume any internal dependency on a constraint
+		 * must be what we are looking for.
+		 */
+		if (deprec->refclassid == ConstraintRelationId &&
+			deprec->refobjsubid == 0 &&
+			deprec->deptype == DEPENDENCY_INTERNAL)
+		{
+			constraintId = deprec->refobjid;
+			break;
+		}
+	}
+
+	systable_endscan(scan);
+	heap_close(depRel, AccessShareLock);
+
+	return constraintId;
 }
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index dc53546a05f3b2243750c724a958251359c4d3c6..1ae51246e795c770607cea92241621d907b23c1d 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.167 2007/11/15 21:14:33 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.168 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -80,8 +80,6 @@ static bool relationHasPrimaryKey(Relation rel);
  *		to index on.
  * 'predicate': the partial-index condition, or NULL if none.
  * 'options': reloptions from WITH (in list-of-DefElem form).
- * 'src_options': reloptions from the source index, if this is a cloned
- *		index produced by CREATE TABLE LIKE ... INCLUDING INDEXES
  * 'unique': make the index enforce uniqueness.
  * 'primary': mark the index as a primary key in the catalogs.
  * 'isconstraint': index is for a PRIMARY KEY or UNIQUE constraint,
@@ -103,7 +101,6 @@ DefineIndex(RangeVar *heapRelation,
 			List *attributeList,
 			Expr *predicate,
 			List *options,
-			char *src_options,
 			bool unique,
 			bool primary,
 			bool isconstraint,
@@ -396,16 +393,9 @@ DefineIndex(RangeVar *heapRelation,
 	}
 
 	/*
-	 * Parse AM-specific options, convert to text array form, validate.  The
-	 * src_options introduced due to using indexes via the "CREATE LIKE
-	 * INCLUDING INDEXES" statement also need to be merged here
+	 * Parse AM-specific options, convert to text array form, validate.
 	 */
-	if (src_options)
-		reloptions = unflatten_reloptions(src_options);
-	else
-		reloptions = (Datum) 0;
-
-	reloptions = transformRelOptions(reloptions, options, false, false);
+	reloptions = transformRelOptions((Datum) 0, options, false, false);
 
 	(void) index_reloptions(amoptions, reloptions, true);
 
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 285bc23496708da17f739d94dc021c8c051f415b..2310c821d03b7d710f798f182660fc82425798e7 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.236 2007/11/15 21:14:33 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.237 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3795,7 +3795,6 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
 				stmt->indexParams,		/* parameters */
 				(Expr *) stmt->whereClause,
 				stmt->options,
-				stmt->src_options,
 				stmt->unique,
 				stmt->primary,
 				stmt->isconstraint,
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 17de2ff3b8807932799e199fd67b2a92ba2b423f..ebee72f80c7897bb7822b3e68df86a571b8f5247 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.385 2007/11/15 22:25:15 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.386 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2195,7 +2195,6 @@ _copyIndexStmt(IndexStmt *from)
 	COPY_STRING_FIELD(tableSpace);
 	COPY_NODE_FIELD(indexParams);
 	COPY_NODE_FIELD(options);
-	COPY_STRING_FIELD(src_options);
 	COPY_NODE_FIELD(whereClause);
 	COPY_SCALAR_FIELD(unique);
 	COPY_SCALAR_FIELD(primary);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 115436237196a956db39f45ae1a05574b73500f3..ebca3370dfabed93e8043d3a1727cb86ac617b07 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.315 2007/11/15 22:25:15 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.316 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1046,7 +1046,6 @@ _equalIndexStmt(IndexStmt *a, IndexStmt *b)
 	COMPARE_STRING_FIELD(tableSpace);
 	COMPARE_NODE_FIELD(indexParams);
 	COMPARE_NODE_FIELD(options);
-	COMPARE_STRING_FIELD(src_options);
 	COMPARE_NODE_FIELD(whereClause);
 	COMPARE_SCALAR_FIELD(unique);
 	COMPARE_SCALAR_FIELD(primary);
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 7d3952c86bd5e501f8a9b21ec9eedba650922f7c..ee56af2bc84faed7848bb15bdcc4b535b80d0435 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.318 2007/11/15 22:25:15 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.319 2007/12/01 23:44:44 tgl Exp $
  *
  * NOTES
  *	  Every node type that can appear in stored rules' parsetrees *must*
@@ -1546,7 +1546,6 @@ _outIndexStmt(StringInfo str, IndexStmt *node)
 	WRITE_STRING_FIELD(tableSpace);
 	WRITE_NODE_FIELD(indexParams);
 	WRITE_NODE_FIELD(options);
-	WRITE_STRING_FIELD(src_options);
 	WRITE_NODE_FIELD(whereClause);
 	WRITE_BOOL_FIELD(unique);
 	WRITE_BOOL_FIELD(primary);
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 2ff6f9274d717ba946debe202e35ef303da40449..a53f01c32abe797d7c1f582da4614df6f09de69b 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -19,7 +19,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *	$PostgreSQL: pgsql/src/backend/parser/parse_utilcmd.c,v 2.6 2007/11/15 21:14:37 momjian Exp $
+ *	$PostgreSQL: pgsql/src/backend/parser/parse_utilcmd.c,v 2.7 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,6 +28,8 @@
 
 #include "access/genam.h"
 #include "access/heapam.h"
+#include "access/reloptions.h"
+#include "catalog/dependency.h"
 #include "catalog/heap.h"
 #include "catalog/index.h"
 #include "catalog/namespace.h"
@@ -675,13 +677,15 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
 		}
 	}
 
+	/*
+	 * Likewise, copy indexes if requested
+	 */
 	if (including_indexes && relation->rd_rel->relhasindex)
 	{
-		AttrNumber *attmap;
+		AttrNumber *attmap = varattnos_map_schema(tupleDesc, cxt->columns);
 		List	   *parent_indexes;
 		ListCell   *l;
 
-		attmap = varattnos_map_schema(tupleDesc, cxt->columns);
 		parent_indexes = RelationGetIndexList(relation);
 
 		foreach(l, parent_indexes)
@@ -693,14 +697,12 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
 			parent_index = index_open(parent_index_oid, AccessShareLock);
 
 			/* Build CREATE INDEX statement to recreate the parent_index */
-			index_stmt = generateClonedIndexStmt(cxt, parent_index,
-												 attmap);
+			index_stmt = generateClonedIndexStmt(cxt, parent_index, attmap);
 
-			/* Add the new IndexStmt to the create context */
+			/* Save it in the inh_indexes list for the time being */
 			cxt->inh_indexes = lappend(cxt->inh_indexes, index_stmt);
 
-			/* Keep our lock on the index till xact commit */
-			index_close(parent_index, NoLock);
+			index_close(parent_index, AccessShareLock);
 		}
 	}
 
@@ -713,54 +715,62 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
 }
 
 /*
- * Generate an IndexStmt entry using information from an already
- * existing index "source_idx".
- *
- * Note: Much of this functionality is cribbed from pg_get_indexdef.
+ * Generate an IndexStmt node using information from an already existing index
+ * "source_idx".  Attribute numbers should be adjusted according to attmap.
  */
 static IndexStmt *
 generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
 						AttrNumber *attmap)
 {
-	HeapTuple	ht_idx;
+	Oid			source_relid = RelationGetRelid(source_idx);
 	HeapTuple	ht_idxrel;
-	HeapTuple	ht_am;
-	Form_pg_index idxrec;
+	HeapTuple	ht_idx;
 	Form_pg_class idxrelrec;
+	Form_pg_index idxrec;
 	Form_pg_am	amrec;
-	List	   *indexprs = NIL;
+	oidvector  *indclass;
+	IndexStmt  *index;
+	List	   *indexprs;
 	ListCell   *indexpr_item;
 	Oid			indrelid;
-	Oid			source_relid;
 	int			keyno;
 	Oid			keycoltype;
-	Datum		indclassDatum;
-	Datum		indoptionDatum;
+	Datum		datum;
 	bool		isnull;
-	oidvector  *indclass;
-	int2vector *indoption;
-	IndexStmt  *index;
-	Datum		reloptions;
 
-	source_relid = RelationGetRelid(source_idx);
+	/*
+	 * Fetch pg_class tuple of source index.  We can't use the copy in the
+	 * relcache entry because it doesn't include optional fields.
+	 */
+	ht_idxrel = SearchSysCache(RELOID,
+							   ObjectIdGetDatum(source_relid),
+							   0, 0, 0);
+	if (!HeapTupleIsValid(ht_idxrel))
+		elog(ERROR, "cache lookup failed for relation %u", source_relid);
+	idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
 
-	/* Fetch pg_index tuple for source index */
-	ht_idx = SearchSysCache(INDEXRELID,
-							ObjectIdGetDatum(source_relid),
-							0, 0, 0);
-	if (!HeapTupleIsValid(ht_idx))
-		elog(ERROR, "cache lookup failed for index %u", source_relid);
+	/* Fetch pg_index tuple for source index from relcache entry */
+	ht_idx = source_idx->rd_indextuple;
 	idxrec = (Form_pg_index) GETSTRUCT(ht_idx);
-
-	Assert(source_relid == idxrec->indexrelid);
 	indrelid = idxrec->indrelid;
 
+	/* Fetch pg_am tuple for source index from relcache entry */
+	amrec = source_idx->rd_am;
+
+	/* Must get indclass the hard way, since it's not stored in relcache */
+	datum = SysCacheGetAttr(INDEXRELID, ht_idx,
+							Anum_pg_index_indclass, &isnull);
+	Assert(!isnull);
+	indclass = (oidvector *) DatumGetPointer(datum);
+
+	/* Begin building the IndexStmt */
 	index = makeNode(IndexStmt);
+	index->relation = cxt->relation;
+	index->accessMethod = pstrdup(NameStr(amrec->amname));
+	index->tableSpace = get_tablespace_name(source_idx->rd_node.spcNode);
 	index->unique = idxrec->indisunique;
-	index->concurrent = false;
 	index->primary = idxrec->indisprimary;
-	index->relation = cxt->relation;
-	index->isconstraint = false;
+	index->concurrent = false;
 
 	/*
 	 * We don't try to preserve the name of the source index; instead, just
@@ -768,65 +778,40 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
 	 */
 	index->idxname = NULL;
 
-	/* Must get indclass and indoption the hard way */
-	indclassDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
-									Anum_pg_index_indclass, &isnull);
-	Assert(!isnull);
-	indclass = (oidvector *) DatumGetPointer(indclassDatum);
-	indoptionDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
-									 Anum_pg_index_indoption, &isnull);
-	Assert(!isnull);
-	indoption = (int2vector *) DatumGetPointer(indoptionDatum);
-
-	/* Fetch pg_class tuple of source index */
-	ht_idxrel = SearchSysCache(RELOID,
-							   ObjectIdGetDatum(source_relid),
-							   0, 0, 0);
-	if (!HeapTupleIsValid(ht_idxrel))
-		elog(ERROR, "cache lookup failed for relation %u", source_relid);
-
 	/*
-	 * Store the reloptions for later use by this new index
+	 * If the index is marked PRIMARY, it's certainly from a constraint;
+	 * else, if it's not marked UNIQUE, it certainly isn't; else, we have
+	 * to search pg_depend to see if there's an associated unique constraint.
 	 */
-	reloptions = SysCacheGetAttr(RELOID, ht_idxrel,
-								 Anum_pg_class_reloptions, &isnull);
-	if (!isnull)
-		index->src_options = flatten_reloptions(source_relid);
-
-	idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
-
-	/* Fetch pg_am tuple for the index's access method */
-	ht_am = SearchSysCache(AMOID,
-						   ObjectIdGetDatum(idxrelrec->relam),
-						   0, 0, 0);
-	if (!HeapTupleIsValid(ht_am))
-		elog(ERROR, "cache lookup failed for access method %u",
-			 idxrelrec->relam);
-	amrec = (Form_pg_am) GETSTRUCT(ht_am);
-	index->accessMethod = pstrdup(NameStr(amrec->amname));
+	if (index->primary)
+		index->isconstraint = true;
+	else if (!index->unique)
+		index->isconstraint = false;
+	else
+		index->isconstraint = OidIsValid(get_index_constraint(source_relid));
 
 	/* Get the index expressions, if any */
-	if (!heap_attisnull(ht_idx, Anum_pg_index_indexprs))
+	datum = SysCacheGetAttr(INDEXRELID, ht_idx,
+							Anum_pg_index_indexprs, &isnull);
+	if (!isnull)
 	{
-		Datum		exprsDatum;
-		bool		isnull;
 		char	   *exprsString;
 
-		exprsDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
-									 Anum_pg_index_indexprs, &isnull);
-		exprsString = DatumGetCString(DirectFunctionCall1(textout,
-														  exprsDatum));
-		Assert(!isnull);
+		exprsString = DatumGetCString(DirectFunctionCall1(textout, datum));
 		indexprs = (List *) stringToNode(exprsString);
 	}
+	else
+		indexprs = NIL;
 
-	indexpr_item = list_head(indexprs);
+	/* Build the list of IndexElem */
+	index->indexParams = NIL;
 
+	indexpr_item = list_head(indexprs);
 	for (keyno = 0; keyno < idxrec->indnatts; keyno++)
 	{
 		IndexElem  *iparam;
 		AttrNumber	attnum = idxrec->indkey.values[keyno];
-		int16		opt = indoption->values[keyno];
+		int16		opt = source_idx->rd_indoption[keyno];
 
 		iparam = makeNode(IndexElem);
 
@@ -849,11 +834,14 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
 			if (indexpr_item == NULL)
 				elog(ERROR, "too few entries in indexprs list");
 			indexkey = (Node *) lfirst(indexpr_item);
+			indexpr_item = lnext(indexpr_item);
+
+			/* OK to modify indexkey since we are working on a private copy */
 			change_varattnos_of_a_node(indexkey, attmap);
+
 			iparam->name = NULL;
 			iparam->expr = indexkey;
 
-			indexpr_item = lnext(indexpr_item);
 			keycoltype = exprType(indexkey);
 		}
 
@@ -866,40 +854,50 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
 		/* Adjust options if necessary */
 		if (amrec->amcanorder)
 		{
-			/* If it supports sort ordering, report DESC and NULLS opts */
+			/*
+			 * If it supports sort ordering, copy DESC and NULLS opts.
+			 * Don't set non-default settings unnecessarily, though,
+			 * so as to improve the chance of recognizing equivalence
+			 * to constraint indexes.
+			 */
 			if (opt & INDOPTION_DESC)
+			{
 				iparam->ordering = SORTBY_DESC;
-			if (opt & INDOPTION_NULLS_FIRST)
-				iparam->nulls_ordering = SORTBY_NULLS_FIRST;
+				if ((opt & INDOPTION_NULLS_FIRST) == 0)
+					iparam->nulls_ordering = SORTBY_NULLS_LAST;
+			}
+			else
+			{
+				if (opt & INDOPTION_NULLS_FIRST)
+					iparam->nulls_ordering = SORTBY_NULLS_FIRST;
+			}
 		}
 
 		index->indexParams = lappend(index->indexParams, iparam);
 	}
 
-	/* Use the same tablespace as the source index */
-	index->tableSpace = get_tablespace_name(source_idx->rd_node.spcNode);
+	/* Copy reloptions if any */
+	datum = SysCacheGetAttr(RELOID, ht_idxrel,
+							Anum_pg_class_reloptions, &isnull);
+	if (!isnull)
+		index->options = untransformRelOptions(datum);
 
 	/* If it's a partial index, decompile and append the predicate */
-	if (!heap_attisnull(ht_idx, Anum_pg_index_indpred))
+	datum = SysCacheGetAttr(INDEXRELID, ht_idx,
+							Anum_pg_index_indpred, &isnull);
+	if (!isnull)
 	{
-		Datum		pred_datum;
-		bool		isnull;
 		char	   *pred_str;
 
 		/* Convert text string to node tree */
-		pred_datum = SysCacheGetAttr(INDEXRELID, ht_idx,
-									 Anum_pg_index_indpred, &isnull);
-		Assert(!isnull);
-		pred_str = DatumGetCString(DirectFunctionCall1(textout,
-													   pred_datum));
+		pred_str = DatumGetCString(DirectFunctionCall1(textout, datum));
 		index->whereClause = (Node *) stringToNode(pred_str);
+		/* Adjust attribute numbers */
 		change_varattnos_of_a_node(index->whereClause, attmap);
 	}
 
 	/* Clean up */
-	ReleaseSysCache(ht_idx);
 	ReleaseSysCache(ht_idxrel);
-	ReleaseSysCache(ht_am);
 
 	return index;
 }
@@ -924,11 +922,11 @@ get_opclass(Oid opclass, Oid actual_datatype)
 		elog(ERROR, "cache lookup failed for opclass %u", opclass);
 	opc_rec = (Form_pg_opclass) GETSTRUCT(ht_opc);
 
-	if (!OidIsValid(actual_datatype) ||
-		GetDefaultOpClass(actual_datatype, opc_rec->opcmethod) != opclass)
+	if (GetDefaultOpClass(actual_datatype, opc_rec->opcmethod) != opclass)
 	{
+		/* For simplicity, we always schema-qualify the name */
 		char	   *nsp_name = get_namespace_name(opc_rec->opcnamespace);
-		char	   *opc_name = NameStr(opc_rec->opcname);
+		char	   *opc_name = pstrdup(NameStr(opc_rec->opcname));
 
 		result = list_make2(makeString(nsp_name), makeString(opc_name));
 	}
@@ -940,8 +938,8 @@ get_opclass(Oid opclass, Oid actual_datatype)
 
 /*
  * transformIndexConstraints
- *		Handle UNIQUE and PRIMARY KEY constraints, which create
- *		indexes. We also merge index definitions arising from
+ *		Handle UNIQUE and PRIMARY KEY constraints, which create indexes.
+ *		We also merge in any index definitions arising from
  *		LIKE ... INCLUDING INDEXES.
  */
 static void
@@ -960,7 +958,30 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
 	{
 		Constraint *constraint = (Constraint *) lfirst(lc);
 
+		Assert(IsA(constraint, Constraint));
+		Assert(constraint->contype == CONSTR_PRIMARY ||
+			   constraint->contype == CONSTR_UNIQUE);
+
 		index = transformIndexConstraint(constraint, cxt);
+
+		indexlist = lappend(indexlist, index);
+	}
+
+	/* Add in any indexes defined by LIKE ... INCLUDING INDEXES */
+	foreach(lc, cxt->inh_indexes)
+	{
+		index = (IndexStmt *) lfirst(lc);
+
+		if (index->primary)
+		{
+			if (cxt->pkey != NULL)
+				ereport(ERROR,
+						(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+						 errmsg("multiple primary keys for table \"%s\" are not allowed",
+								cxt->relation->relname)));
+			cxt->pkey = index;
+		}
+
 		indexlist = lappend(indexlist, index);
 	}
 
@@ -995,8 +1016,11 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
 		{
 			IndexStmt  *priorindex = lfirst(k);
 
-			if (equal(index->indexParams, priorindex->indexParams))
+			if (equal(index->indexParams, priorindex->indexParams) &&
+				equal(index->whereClause, priorindex->whereClause) &&
+				strcmp(index->accessMethod, priorindex->accessMethod) == 0)
 			{
+				priorindex->unique |= index->unique;
 				/*
 				 * If the prior index is as yet unnamed, and this one is
 				 * named, then transfer the name to the prior index. This
@@ -1013,27 +1037,13 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
 		if (keep)
 			cxt->alist = lappend(cxt->alist, index);
 	}
-
-	/* Copy indexes defined by LIKE ... INCLUDING INDEXES */
-	foreach(lc, cxt->inh_indexes)
-	{
-		index = (IndexStmt *) lfirst(lc);
-
-		if (index->primary)
-		{
-			if (cxt->pkey)
-				ereport(ERROR,
-						(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
-						 errmsg("multiple primary keys for table \"%s\" are not allowed",
-								cxt->relation->relname)));
-
-			cxt->pkey = index;
-		}
-
-		cxt->alist = lappend(cxt->alist, index);
-	}
 }
 
+/*
+ * transformIndexConstraint
+ *		Transform one UNIQUE or PRIMARY KEY constraint for
+ *		transformIndexConstraints.
+ */
 static IndexStmt *
 transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
 {
@@ -1041,13 +1051,10 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
 	ListCell   *keys;
 	IndexElem  *iparam;
 
-	Assert(constraint->contype == CONSTR_PRIMARY ||
-		   constraint->contype == CONSTR_UNIQUE);
-
 	index = makeNode(IndexStmt);
+
 	index->unique = true;
 	index->primary = (constraint->contype == CONSTR_PRIMARY);
-
 	if (index->primary)
 	{
 		if (cxt->pkey != NULL)
@@ -1771,7 +1778,7 @@ transformAlterTableStmt(AlterTableStmt *stmt, const char *queryString)
 
 	/*
 	 * transformIndexConstraints wants cxt.alist to contain only index
-	 * statements, so transfer anything we already have into save_alist.
+	 * statements, so transfer anything we already have into save_alist
 	 * immediately.
 	 */
 	save_alist = cxt.alist;
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 9a1e877820dd42e3a0c92bb9332826d8c03ad3bb..bcbfe251b7f07e19a251c5720ebf9af7ebab8304 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.287 2007/11/15 21:14:38 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.288 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -924,7 +924,6 @@ ProcessUtility(Node *parsetree,
 							stmt->indexParams,	/* parameters */
 							(Expr *) stmt->whereClause,
 							stmt->options,
-							stmt->src_options,
 							stmt->unique,
 							stmt->primary,
 							stmt->isconstraint,
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 168da20aa23d0d998774b3eb4752f91ad0108841..8e4d5c90cd3e76f5bc3f306dc01d249033fc9316 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.265 2007/11/15 21:14:39 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.266 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -133,7 +133,6 @@ 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 constraintId);
 static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
 			 int prettyFlags);
 static void make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
@@ -195,6 +194,7 @@ static char *generate_relation_name(Oid relid);
 static char *generate_function_name(Oid funcid, int nargs, Oid *argtypes);
 static char *generate_operator_name(Oid operid, Oid arg1, Oid arg2);
 static text *string_to_text(char *str);
+static char *flatten_reloptions(Oid relid);
 
 #define only_marker(rte)  ((rte)->inh ? "" : "ONLY ")
 
@@ -1384,68 +1384,6 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS)
 }
 
 
-/*
- * get_constraint_index
- *		Given the OID of a unique or primary-key constraint, return the
- *		OID of the underlying unique index.
- *
- * Return InvalidOid if the index couldn't be found; this suggests the
- * given OID is bogus, but we leave it to caller to decide what to do.
- */
-static Oid
-get_constraint_index(Oid constraintId)
-{
-	Oid			indexId = InvalidOid;
-	Relation	depRel;
-	ScanKeyData key[3];
-	SysScanDesc scan;
-	HeapTuple	tup;
-
-	/* Search the dependency table for the dependent index */
-	depRel = heap_open(DependRelationId, AccessShareLock);
-
-	ScanKeyInit(&key[0],
-				Anum_pg_depend_refclassid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(ConstraintRelationId));
-	ScanKeyInit(&key[1],
-				Anum_pg_depend_refobjid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(constraintId));
-	ScanKeyInit(&key[2],
-				Anum_pg_depend_refobjsubid,
-				BTEqualStrategyNumber, F_INT4EQ,
-				Int32GetDatum(0));
-
-	scan = systable_beginscan(depRel, DependReferenceIndexId, 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 an index on the constraint
-		 * must be what we are looking for.  (The relkind test is just
-		 * paranoia; there shouldn't be any such dependencies otherwise.)
-		 */
-		if (deprec->classid == RelationRelationId &&
-			deprec->objsubid == 0 &&
-			deprec->deptype == DEPENDENCY_INTERNAL &&
-			get_rel_relkind(deprec->objid) == RELKIND_INDEX)
-		{
-			indexId = deprec->objid;
-			break;
-		}
-	}
-
-	systable_endscan(scan);
-	heap_close(depRel, AccessShareLock);
-
-	return indexId;
-}
-
-
 /*
  * deparse_expression			- General utility for deparsing expressions
  *
@@ -5507,7 +5445,7 @@ string_to_text(char *str)
 /*
  * Generate a C string representing a relation's reloptions, or NULL if none.
  */
-char *
+static char *
 flatten_reloptions(Oid relid)
 {
 	char	   *result = NULL;
@@ -5543,32 +5481,3 @@ flatten_reloptions(Oid relid)
 
 	return result;
 }
-
-/*
- * Generate an Array Datum representing a relation's reloptions using
- * a C string
- */
-Datum
-unflatten_reloptions(char *reloptstring)
-{
-	Datum		result = (Datum) 0;
-
-	if (reloptstring)
-	{
-		Datum		sep,
-					relopts;
-
-		/*
-		 * We want to use text_to_array(reloptstring, ', ') --- but
-		 * DirectFunctionCall2(text_to_array) does not work, because
-		 * text_to_array() relies on fcinfo to be valid.  So use
-		 * OidFunctionCall2.
-		 */
-		sep = DirectFunctionCall1(textin, CStringGetDatum(", "));
-		relopts = DirectFunctionCall1(textin, CStringGetDatum(reloptstring));
-
-		result = OidFunctionCall2(F_TEXT_TO_ARRAY, relopts, sep);
-	}
-
-	return result;
-}
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index 1c5aa3526cbc891ff6a9d928eb6dc81a56cd1e6e..f6a7c42c19db17d2ba1af93282587f0bda9682b6 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -11,7 +11,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.3 2007/01/05 22:19:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.4 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -23,6 +23,8 @@
 extern Datum transformRelOptions(Datum oldOptions, List *defList,
 					bool ignoreOids, bool isReset);
 
+extern List *untransformRelOptions(Datum options);
+
 extern void parseRelOptions(Datum options, int numkeywords,
 				const char *const * keywords,
 				char **values, bool validate);
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index 1b238d8d8a93ce4bb31bee8d77ad7d8d5d256f14..637a7a93712f7a3a3ed3e3c8a500153d15a64e3f 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.31 2007/11/15 21:14:42 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.32 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -207,6 +207,10 @@ extern bool sequenceIsOwned(Oid seqId, Oid *tableId, int32 *colId);
 
 extern void markSequenceUnowned(Oid seqId);
 
+extern Oid	get_constraint_index(Oid constraintId);
+
+extern Oid	get_index_constraint(Oid indexId);
+
 /* in pg_shdepend.c */
 
 extern void recordSharedDependencyOn(ObjectAddress *depender,
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 99621d3b26e38c3153a484f15970ceafd294ea43..152061239f503ed6b3acdbdaeef0975d669c9609 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.86 2007/11/15 22:25:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.87 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,7 +26,6 @@ extern void DefineIndex(RangeVar *heapRelation,
 			List *attributeList,
 			Expr *predicate,
 			List *options,
-			char *src_options,
 			bool unique,
 			bool primary,
 			bool isconstraint,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 51d760ef564cdb13afe7befe9eaf23cdd912ec9b..d7055140a5fe20050a76c5ad10f7238da9557561 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.356 2007/11/15 22:25:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.357 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1540,7 +1540,6 @@ typedef struct IndexStmt
 	char	   *tableSpace;		/* tablespace, or NULL to use parent's */
 	List	   *indexParams;	/* a list of IndexElem */
 	List	   *options;		/* options from WITH clause */
-	char	   *src_options;	/* relopts inherited from source index */
 	Node	   *whereClause;	/* qualification (partial-index predicate) */
 	bool		unique;			/* is index unique? */
 	bool		primary;		/* is index on primary key? */
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index cf9e03fcf3d3e1faa68e53e96e7d0dfc01778435..d4fb1262cdf9ec0cb6b2938805e7af09d31e2fcc 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.306 2007/11/15 21:14:45 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.307 2007/12/01 23:44:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -566,8 +566,6 @@ extern List *deparse_context_for_plan(Node *outer_plan, Node *inner_plan,
 extern const char *quote_identifier(const char *ident);
 extern char *quote_qualified_identifier(const char *namespace,
 						   const char *ident);
-extern char *flatten_reloptions(Oid relid);
-extern Datum unflatten_reloptions(char *reloptstring);
 
 /* tid.c */
 extern Datum tidin(PG_FUNCTION_ARGS);
diff --git a/src/test/regress/expected/inherit.out b/src/test/regress/expected/inherit.out
index 40dfaeda902a0c75e0f51b8e66fc86c2190f5319..f81776fe80463dac11247b8cab439d3415f96030 100644
--- a/src/test/regress/expected/inherit.out
+++ b/src/test/regress/expected/inherit.out
@@ -634,6 +634,7 @@ SELECT * FROM inhg; /* Two records with three columns in order x=x, xx=text, y=y
 
 DROP TABLE inhg;
 CREATE TABLE inhg (x text, LIKE inhx INCLUDING INDEXES, y text); /* copies indexes */
+NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "inhg_pkey" for table "inhg"
 INSERT INTO inhg VALUES (5, 10);
 INSERT INTO inhg VALUES (20, 10); -- should fail
 ERROR:  duplicate key value violates unique constraint "inhg_pkey"
@@ -647,6 +648,7 @@ CREATE UNIQUE INDEX inhz_xx_idx on inhz (xx) WHERE xx <> 'test';
 /* Ok to create multiple unique indexes */
 CREATE TABLE inhg (x text UNIQUE, LIKE inhz INCLUDING INDEXES);
 NOTICE:  CREATE TABLE / UNIQUE will create implicit index "inhg_x_key" for table "inhg"
+NOTICE:  CREATE TABLE / UNIQUE will create implicit index "inhg_yy_key" for table "inhg"
 INSERT INTO inhg (xx, yy, x) VALUES ('test', 5, 10);
 INSERT INTO inhg (xx, yy, x) VALUES ('test', 10, 15);
 INSERT INTO inhg (xx, yy, x) VALUES ('foo', 10, 15); -- should fail