at7-alt-index-opfamily.patch

text/plain

Filename: at7-alt-index-opfamily.patch
Type: text/plain
Part: 1
Message: ALTER TYPE 7: avoid index rebuilds/FK validations

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: context
File+
src/backend/catalog/storage.c 0 0
src/backend/commands/indexcmds.c 82 0
src/backend/commands/tablecmds.c 198 0
src/backend/nodes/copyfuncs.c 1 0
src/backend/nodes/equalfuncs.c 1 0
src/backend/nodes/outfuncs.c 1 0
src/include/commands/defrem.h 7 1
src/include/nodes/parsenodes.h 1 0
src/test/regress/expected/alter_table.out 70 0
src/test/regress/sql/alter_table.sql 3 0
*** a/src/backend/catalog/storage.c
--- b/src/backend/catalog/storage.c
***************
*** 221,229 **** RelationPreserveStorage(RelFileNode rnode)
  		next = pending->next;
  		if (RelFileNodeEquals(rnode, pending->relnode))
  		{
- 			/* we should only find delete-on-abort entries, else trouble */
- 			if (pending->atCommit)
- 				elog(ERROR, "cannot preserve a delete-on-commit relation");
  			/* unlink and delete list entry */
  			if (prev)
  				prev->next = next;
--- 221,226 ----
*** a/src/backend/commands/indexcmds.c
--- b/src/backend/commands/indexcmds.c
***************
*** 73,78 **** static bool relationHasPrimaryKey(Relation rel);
--- 73,154 ----
  
  
  /*
+  * GetIndexCompatibilityFeatures
+  *		Select operator classes and exclusion operators for a prospective index.
+  *
+  * Mostly a support function for MakeIndexCompatible().  Omits some of the
+  * checks of DefineIndex, as the index definition always has an internal
+  * genesis.  Errors arising from the attribute list still apply.
+  *
+  * 'heapRelation': the relation the index would apply to.
+  * 'accessMethodName': name of the AM to use.
+  * 'attributeList': a list of IndexElem specifying columns and expressions
+  *		to index on.
+  * 'exclusionOpNames': list of names of exclusion-constraint operators,
+  *		or NIL if not an exclusion constraint.
+  *
+  * Returns a palloc'd array of operator class OIDs and another palloc'd array of
+  * exclusion operator OIDs.  Each has one element per index column.
+  */
+ void
+ GetIndexCompatibilityAspects(RangeVar *heapRelation,
+ 							 char *accessMethodName,
+ 							 List *attributeList,
+ 							 List *exclusionOpNames,
+ 							 Oid **opClasses,
+ 							 Oid **exclusionOps)
+ {
+ 	Oid		   *classObjectId;
+ 	Oid			accessMethodId;
+ 	HeapTuple	tuple;
+ 	Form_pg_am	accessMethodForm;
+ 	bool		amcanorder;
+ 	RegProcedure amoptions;
+ 	int16	   *coloptions;
+ 	IndexInfo  *indexInfo;
+ 	int			numberOfAttributes;
+ 
+ 	numberOfAttributes = list_length(attributeList);
+ 	Assert(numberOfAttributes > 0);
+ 	Assert(numberOfAttributes <= INDEX_MAX_KEYS);
+ 
+ 	/* look up the access method */
+ 	tuple = SearchSysCache1(AMNAME, PointerGetDatum(accessMethodName));
+ 	if (!HeapTupleIsValid(tuple))
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_UNDEFINED_OBJECT),
+ 				 errmsg("access method \"%s\" does not exist",
+ 						accessMethodName)));
+ 	accessMethodId = HeapTupleGetOid(tuple);
+ 	accessMethodForm = (Form_pg_am) GETSTRUCT(tuple);
+ 	amcanorder = accessMethodForm->amcanorder;
+ 	amoptions = accessMethodForm->amoptions;
+ 	ReleaseSysCache(tuple);
+ 
+ 	indexInfo = makeNode(IndexInfo);
+ 	indexInfo->ii_Expressions = NIL;
+ 	indexInfo->ii_ExpressionsState = NIL;
+ 	indexInfo->ii_PredicateState = NIL;
+ 	indexInfo->ii_ExclusionOps = NULL;
+ 	indexInfo->ii_ExclusionProcs = NULL;
+ 	indexInfo->ii_ExclusionStrats = NULL;
+ 	classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
+ 	coloptions = (int16 *) palloc(numberOfAttributes * sizeof(int16));
+ 
+ 	/*
+ 	 * We can pretend isconstraint = false unconditionally.  It only serves to
+ 	 * decide the text of an error message that should never happen for us.
+ 	 */
+ 	ComputeIndexAttrs(indexInfo, classObjectId, coloptions, attributeList,
+ 					  exclusionOpNames, RangeVarGetRelid(heapRelation, false),
+ 					  accessMethodName, accessMethodId, false, amcanorder);
+ 	pfree(coloptions);
+ 
+ 	*opClasses = classObjectId;
+ 	*exclusionOps = indexInfo->ii_ExclusionOps;
+ }
+ 
+ /*
   * DefineIndex
   *		Creates a new index.
   *
***************
*** 103,110 **** static bool relationHasPrimaryKey(Relation rel);
   *		it will be filled later.
   * 'quiet': suppress the NOTICE chatter ordinarily provided for constraints.
   * 'concurrent': avoid blocking writers to the table while building.
   */
! void
  DefineIndex(RangeVar *heapRelation,
  			char *indexRelationName,
  			Oid indexRelationId,
--- 179,188 ----
   *		it will be filled later.
   * 'quiet': suppress the NOTICE chatter ordinarily provided for constraints.
   * 'concurrent': avoid blocking writers to the table while building.
+  *
+  * Returns the OID of the new index relation.
   */
! Oid
  DefineIndex(RangeVar *heapRelation,
  			char *indexRelationName,
  			Oid indexRelationId,
***************
*** 486,492 **** DefineIndex(RangeVar *heapRelation,
  					 concurrent);
  
  	if (!concurrent)
! 		return;					/* We're done, in the standard case */
  
  	/*
  	 * For a concurrent build, it's important to make the catalog entries
--- 564,570 ----
  					 concurrent);
  
  	if (!concurrent)
! 		return indexRelationId; /* We're done, in the standard case */
  
  	/*
  	 * For a concurrent build, it's important to make the catalog entries
***************
*** 768,773 **** DefineIndex(RangeVar *heapRelation,
--- 846,853 ----
  	 * Last thing to do is release the session-level lock on the parent table.
  	 */
  	UnlockRelationIdForSession(&heaprelid, ShareUpdateExclusiveLock);
+ 
+ 	return indexRelationId;
  }
  
  
*** a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c
***************
*** 118,123 **** static List *on_commits = NIL;
--- 118,124 ----
   * a pass determined by subcommand type.
   */
  
+ #define AT_PASS_INVALID			-1		/* placeholder, pending selection */
  #define AT_PASS_DROP			0		/* DROP (all flavors) */
  #define AT_PASS_ALTER_TYPE		1		/* ALTER COLUMN TYPE */
  #define AT_PASS_OLD_INDEX		2		/* re-add existing indexes */
***************
*** 338,344 **** static void ATPrepAlterColumnType(List **wqueue,
  static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
  					  const char *colName, TypeName *typeName, LOCKMODE lockmode);
  static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode);
! static void ATPostAlterTypeParse(char *cmd, List **wqueue, LOCKMODE lockmode);
  static void change_owner_recurse_to_sequences(Oid relationOid,
  								  Oid newOwnerId, LOCKMODE lockmode);
  static void ATExecClusterOn(Relation rel, const char *indexName, LOCKMODE lockmode);
--- 339,347 ----
  static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
  					  const char *colName, TypeName *typeName, LOCKMODE lockmode);
  static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode);
! static void ATPostAlterTypeParse(Oid oldId, char *cmd,
! 					 List **wqueue, LOCKMODE lockmode, bool newBits);
! static void CheckIndexCompatible(Oid oldId, IndexStmt *stmt);
  static void change_owner_recurse_to_sequences(Oid relationOid,
  								  Oid newOwnerId, LOCKMODE lockmode);
  static void ATExecClusterOn(Relation rel, const char *indexName, LOCKMODE lockmode);
***************
*** 5021,5057 **** ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
  	bool		check_rights;
  	bool		skip_build;
  	bool		quiet;
  
  	Assert(IsA(stmt, IndexStmt));
  
  	/* suppress schema rights check when rebuilding existing index */
  	check_rights = !is_rebuild;
! 	/* skip index build if phase 3 will have to rewrite table anyway */
! 	skip_build = tab->new_bits;
  	/* suppress notices when rebuilding existing index */
  	quiet = is_rebuild;
  
  	/* The IndexStmt has already been through transformIndexStmt */
  
! 	DefineIndex(stmt->relation, /* relation */
! 				stmt->idxname,	/* index name */
! 				InvalidOid,		/* no predefined OID */
! 				stmt->accessMethod,		/* am name */
! 				stmt->tableSpace,
! 				stmt->indexParams,		/* parameters */
! 				(Expr *) stmt->whereClause,
! 				stmt->options,
! 				stmt->excludeOpNames,
! 				stmt->unique,
! 				stmt->primary,
! 				stmt->isconstraint,
! 				stmt->deferrable,
! 				stmt->initdeferred,
! 				true,			/* is_alter_table */
! 				check_rights,
! 				skip_build,
! 				quiet,
! 				false);
  }
  
  /*
--- 5024,5098 ----
  	bool		check_rights;
  	bool		skip_build;
  	bool		quiet;
+ 	Oid			new_index;
  
  	Assert(IsA(stmt, IndexStmt));
  
  	/* suppress schema rights check when rebuilding existing index */
  	check_rights = !is_rebuild;
! 	/* skip index build if phase 3 will do it or we're reusing an old one */
! 	skip_build = tab->new_bits || OidIsValid(stmt->oldNode);
  	/* suppress notices when rebuilding existing index */
  	quiet = is_rebuild;
  
  	/* The IndexStmt has already been through transformIndexStmt */
  
! 	new_index = DefineIndex(stmt->relation,		/* relation */
! 							stmt->idxname,		/* index name */
! 							InvalidOid, /* no predefined OID */
! 							stmt->accessMethod, /* am name */
! 							stmt->tableSpace,
! 							stmt->indexParams,	/* parameters */
! 							(Expr *) stmt->whereClause,
! 							stmt->options,
! 							stmt->excludeOpNames,
! 							stmt->unique,
! 							stmt->primary,
! 							stmt->isconstraint,
! 							stmt->deferrable,
! 							stmt->initdeferred,
! 							true,		/* is_alter_table */
! 							check_rights,
! 							skip_build,
! 							quiet,
! 							false);
! 
! 	/*
! 	 * If CheckIndexCompatible stashed a relfilenode for us, replace the fresh
! 	 * one with that.  This vaguely follows swap_relation_files, but we need
! 	 * not consider the case of a system table.  Indexes inherit relfrozenxid
! 	 * and never have TOAST tables.
! 	 */
! 	if (OidIsValid(stmt->oldNode))
! 	{
! 		Relation	pg_class;
! 		Relation	irel;
! 		HeapTuple	tup;
! 
! 		/* Drop the empty storage just created under DefineIndex. */
! 		irel = index_open(new_index, NoLock);
! 		RelationDropStorage(irel);
! 
! 		/* Update pg_class.relfilenode. */
! 		pg_class = heap_open(RelationRelationId, RowExclusiveLock);
! 		tup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(new_index));
! 		if (!HeapTupleIsValid(tup))		/* shouldn't happen */
! 			elog(ERROR, "cache lookup failed for relation %u", new_index);
! 
! 		((Form_pg_class) GETSTRUCT(tup))->relfilenode = stmt->oldNode;
! 		simple_heap_update(pg_class, &tup->t_self, tup);
! 		CatalogUpdateIndexes(pg_class, tup);
! 		heap_close(pg_class, RowExclusiveLock);
! 
! 		CommandCounterIncrement();
! 
! 		/*
! 		 * The reassigned storage is probably scheduled for deletion, having
! 		 * been attached to a just-DROPped index.  Revive it.
! 		 */
! 		RelationPreserveStorage(irel->rd_node);
! 		index_close(irel, NoLock);
! 	}
  }
  
  /*
***************
*** 6809,6869 **** ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
  }
  
  /*
!  * Cleanup after we've finished all the ALTER TYPE operations for a
!  * particular relation.  We have to drop and recreate all the indexes
!  * and constraints that depend on the altered columns.
   */
  static void
  ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
  {
  	ObjectAddress obj;
! 	ListCell   *l;
  
! 	/*
! 	 * Re-parse the index and constraint definitions, and attach them to the
! 	 * appropriate work queue entries.	We do this before dropping because in
! 	 * the case of a FOREIGN KEY constraint, we might not yet have exclusive
! 	 * lock on the table the constraint is attached to, and we need to get
! 	 * that before dropping.  It's safe because the parser won't actually look
! 	 * at the catalogs to detect the existing entry.
! 	 */
! 	foreach(l, tab->changedIndexDefs)
! 		ATPostAlterTypeParse((char *) lfirst(l), wqueue, lockmode);
! 	foreach(l, tab->changedConstraintDefs)
! 		ATPostAlterTypeParse((char *) lfirst(l), wqueue, lockmode);
! 
! 	/*
! 	 * Now we can drop the existing constraints and indexes --- constraints
! 	 * first, since some of them might depend on the indexes.  In fact, we
! 	 * have to delete FOREIGN KEY constraints before UNIQUE constraints, but
! 	 * we already ordered the constraint list to ensure that would happen. It
! 	 * should be okay to use DROP_RESTRICT here, since nothing else should be
! 	 * depending on these objects.
! 	 */
! 	foreach(l, tab->changedConstraintOids)
  	{
  		obj.classId = ConstraintRelationId;
! 		obj.objectId = lfirst_oid(l);
  		obj.objectSubId = 0;
  		performDeletion(&obj, DROP_RESTRICT);
  	}
! 
! 	foreach(l, tab->changedIndexOids)
  	{
  		obj.classId = RelationRelationId;
! 		obj.objectId = lfirst_oid(l);
  		obj.objectSubId = 0;
  		performDeletion(&obj, DROP_RESTRICT);
  	}
- 
- 	/*
- 	 * The objects will get recreated during subsequent passes over the work
- 	 * queue.
- 	 */
  }
  
  static void
! ATPostAlterTypeParse(char *cmd, List **wqueue, LOCKMODE lockmode)
  {
  	List	   *raw_parsetree_list;
  	List	   *querytree_list;
--- 6850,6895 ----
  }
  
  /*
!  * The pseudo-pass follows AT_PASS_ALTER_TYPE for a particular relation.  Here,
!  * we parse the statements to recreate indexes and constraints that depend on
!  * the altered columns, then drop the current objects.  This parsing cannot come
!  * earlier, because the tuple descriptor must be in final form.  We must drop
!  * FOREIGN KEY constraints before indexes and index-based constraints; we have
!  * already ordered changedConstraintOids accordingly.  We will recreate the
!  * objects during AT_PASS_OLD_INDEX and AT_PASS_OLD_CONSTR.
   */
  static void
  ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
  {
  	ObjectAddress obj;
! 	ListCell   *def;
! 	ListCell   *oid;
  
! 	forboth(oid, tab->changedConstraintOids, def, tab->changedConstraintDefs)
  	{
+ 		ATPostAlterTypeParse(lfirst_oid(oid), (char *) lfirst(def),
+ 							 wqueue, lockmode, tab->new_bits);
+ 
  		obj.classId = ConstraintRelationId;
! 		obj.objectId = lfirst_oid(oid);
  		obj.objectSubId = 0;
  		performDeletion(&obj, DROP_RESTRICT);
  	}
! 	forboth(oid, tab->changedIndexOids, def, tab->changedIndexDefs)
  	{
+ 		ATPostAlterTypeParse(lfirst_oid(oid), (char *) lfirst(def),
+ 							 wqueue, lockmode, tab->new_bits);
+ 
  		obj.classId = RelationRelationId;
! 		obj.objectId = lfirst_oid(oid);
  		obj.objectSubId = 0;
  		performDeletion(&obj, DROP_RESTRICT);
  	}
  }
  
  static void
! ATPostAlterTypeParse(Oid oldId, char *cmd,
! 					 List **wqueue, LOCKMODE lockmode, bool newBits)
  {
  	List	   *raw_parsetree_list;
  	List	   *querytree_list;
***************
*** 6910,6915 **** ATPostAlterTypeParse(char *cmd, List **wqueue, LOCKMODE lockmode)
--- 6936,6944 ----
  					IndexStmt  *stmt = (IndexStmt *) stm;
  					AlterTableCmd *newcmd;
  
+ 					if (!newBits)
+ 						CheckIndexCompatible(oldId, stmt);
+ 
  					rel = relation_openrv(stmt->relation, lockmode);
  					tab = ATGetQueueEntry(wqueue, rel);
  					newcmd = makeNode(AlterTableCmd);
***************
*** 6934,6944 **** ATPostAlterTypeParse(char *cmd, List **wqueue, LOCKMODE lockmode)
--- 6963,6992 ----
  						switch (cmd->subtype)
  						{
  							case AT_AddIndex:
+ 								Assert(IsA(cmd->def, IndexStmt));
+ 								if (!newBits)
+ 									CheckIndexCompatible(get_constraint_index(oldId),
+ 													 (IndexStmt *) cmd->def);
+ 
  								cmd->subtype = AT_ReAddIndex;
  								tab->subcmds[AT_PASS_OLD_INDEX] =
  									lappend(tab->subcmds[AT_PASS_OLD_INDEX], cmd);
  								break;
  							case AT_AddConstraint:
+ 
+ 								/*
+ 								 * Skip foreign key revalidation when the
+ 								 * stored bits aren't changing.
+ 								 * ATAddCheckConstraint does not look at
+ 								 * skip_validation.  This works well in
+ 								 * practice, but it suffers from the same
+ 								 * formal risks as index reuse.  See the
+ 								 * comment at CheckIndexCompatible().
+ 								 */
+ 								if (!newBits)
+ 									((Constraint *) cmd->def)->skip_validation
+ 										= true;
+ 
  								tab->subcmds[AT_PASS_OLD_CONSTR] =
  									lappend(tab->subcmds[AT_PASS_OLD_CONSTR], cmd);
  								break;
***************
*** 6957,6962 **** ATPostAlterTypeParse(char *cmd, List **wqueue, LOCKMODE lockmode)
--- 7005,7102 ----
  	}
  }
  
+ /*
+  * Typical indexes will remain valid across most column type changes not
+  * entailing table rewrites.  We assume continued validity when each column of
+  * an index would have the same operator family before and after the change.  No
+  * formal behavioral contract justifies this, but it fits well in practice.  To
+  * illustrate the formal hazard, consider type "int_regular" and "int_negative",
+  * both covered by a common operator family.  To user, they both behave like the
+  * SQL standard integer type, but the latter internally stores the negation of
+  * its value.  Now suppose an explicit binary-coercion cast between them.  After
+  * a no-work change between these types on a B-tree-indexed column, the operator
+  * family will remain the same, but the sort order inverts.  The operator family
+  * was blameless under its contract.  This arose because we effectively assumed
+  * that a cast had some connection to the B-tree operator family's concept of
+  * equality.  That connection is firm in practice, yet informal.
+  *
+  * We do not document a contract for GIN or GiST operator families.  Only the
+  * GIN operator family "array_ops" has more than one constituent operator class,
+  * and only typmod-only changes to arrays can avoid a rewrite.  Preserving a GIN
+  * index across such a change is safe.  We therefore support GiST and GIN here
+  * using the same rules as for B-tree and hash indexes, but that is mostly
+  * academic.  Any forthcoming contract for GiST or GIN operator families should,
+  * all other things being equal, bolster the validity of this assumption.
+  *
+  * Exclusion constraints raise the question: can we trust that the operator has
+  * the same semantics with the new type?  The operator will fall in the index's
+  * operator family.  For B-tree or hash, the operator will be "=" or "<>",
+  * yielding an affirmative answer from contractual requirements.  For GiST and
+  * GIN, we assume that a similar requirement would fall out of any contract for
+  * their operator families, should one arise.  We therefore support exclusion
+  * constraints without any special treatment, but this is again mostly academic.
+  *
+  * This implementation assumes a general similarity with the old and new
+  * indexes, specifically that they have the same number of columns, and that if
+  * one has an expression column or predicate, both do.  Since the new index
+  * statement comes from pg_get_indexdef on the old index, this had better hold.
+  */
+ static void
+ CheckIndexCompatible(Oid oldId, IndexStmt *stmt)
+ {
+ 	HeapTuple	tup;
+ 	int2		index_natts;
+ 	bool		isnull;
+ 	oidvector  *old_indclass;
+ 	Oid		   *new_indclass;
+ 	Oid		   *new_conexclop;
+ 	int			i;
+ 	Datum		d;
+ 	Relation	irel;
+ 
+ 	/* Get the soon-obsolete pg_index tuple. */
+ 	tup = SearchSysCacheCopy1(INDEXRELID, ObjectIdGetDatum(oldId));
+ 	if (!HeapTupleIsValid(tup))
+ 		elog(ERROR, "cache lookup failed for index %u", oldId);
+ 
+ 	/* We don't handle expressions or predicates. */
+ 	if (!(heap_attisnull(tup, Anum_pg_index_indpred) &&
+ 		  heap_attisnull(tup, Anum_pg_index_indexprs)))
+ 		return;
+ 
+ 	/*
+ 	 * If the old and new operator class of any index column differ in operator
+ 	 * family, the old index may be incompatible.
+ 	 */
+ 	index_natts = ((Form_pg_index) GETSTRUCT(tup))->indnatts;
+ 
+ 	d = SysCacheGetAttr(INDEXRELID, tup, Anum_pg_index_indclass, &isnull);
+ 	Assert(!isnull);
+ 	old_indclass = (oidvector *) DatumGetPointer(d);
+ 
+ 	GetIndexCompatibilityAspects(stmt->relation,
+ 								 stmt->accessMethod,
+ 								 stmt->indexParams,
+ 								 stmt->excludeOpNames,
+ 								 &new_indclass,
+ 								 &new_conexclop);
+ 
+ 	for (i = 0; i < index_natts; i++)
+ 	{
+ 		Oid			old_opc = old_indclass->values[i];
+ 		Oid			new_opc = new_indclass[i];
+ 
+ 		if (old_opc != new_opc
+ 			&& get_opclass_family(old_opc) != get_opclass_family(new_opc))
+ 			return;
+ 	}
+ 
+ 	/* The old index is compatible.  Keep its relfilenode for ATExecAddIndex. */
+ 	irel = index_open(oldId, NoLock);
+ 	stmt->oldNode = irel->rd_node.relNode;
+ 	index_close(irel, NoLock);
+ }
+ 
  
  /*
   * ALTER TABLE OWNER
*** a/src/backend/nodes/copyfuncs.c
--- b/src/backend/nodes/copyfuncs.c
***************
*** 2715,2720 **** _copyIndexStmt(IndexStmt *from)
--- 2715,2721 ----
  	COPY_SCALAR_FIELD(deferrable);
  	COPY_SCALAR_FIELD(initdeferred);
  	COPY_SCALAR_FIELD(concurrent);
+ 	COPY_SCALAR_FIELD(oldNode);
  
  	return newnode;
  }
*** a/src/backend/nodes/equalfuncs.c
--- b/src/backend/nodes/equalfuncs.c
***************
*** 1219,1224 **** _equalIndexStmt(IndexStmt *a, IndexStmt *b)
--- 1219,1225 ----
  	COMPARE_SCALAR_FIELD(deferrable);
  	COMPARE_SCALAR_FIELD(initdeferred);
  	COMPARE_SCALAR_FIELD(concurrent);
+ 	COMPARE_SCALAR_FIELD(oldNode);
  
  	return true;
  }
*** a/src/backend/nodes/outfuncs.c
--- b/src/backend/nodes/outfuncs.c
***************
*** 1887,1892 **** _outIndexStmt(StringInfo str, IndexStmt *node)
--- 1887,1893 ----
  	WRITE_BOOL_FIELD(deferrable);
  	WRITE_BOOL_FIELD(initdeferred);
  	WRITE_BOOL_FIELD(concurrent);
+ 	WRITE_OID_FIELD(oldNode);
  }
  
  static void
*** a/src/include/commands/defrem.h
--- b/src/include/commands/defrem.h
***************
*** 18,24 ****
  
  
  /* commands/indexcmds.c */
! extern void DefineIndex(RangeVar *heapRelation,
  			char *indexRelationName,
  			Oid indexRelationId,
  			char *accessMethodName,
--- 18,24 ----
  
  
  /* commands/indexcmds.c */
! extern Oid DefineIndex(RangeVar *heapRelation,
  			char *indexRelationName,
  			Oid indexRelationId,
  			char *accessMethodName,
***************
*** 49,54 **** extern char *ChooseIndexName(const char *tabname, Oid namespaceId,
--- 49,60 ----
  				List *colnames, List *exclusionOpNames,
  				bool primary, bool isconstraint);
  extern List *ChooseIndexColumnNames(List *indexElems);
+ extern void GetIndexCompatibilityAspects(RangeVar *heapRelation,
+ 							 char *accessMethodName,
+ 							 List *attributeList,
+ 							 List *exclusionOpNames,
+ 							 Oid **opClasses,
+ 							 Oid **exclusionOps);
  extern Oid	GetDefaultOpClass(Oid type_id, Oid am_id);
  
  /* commands/functioncmds.c */
*** a/src/include/nodes/parsenodes.h
--- b/src/include/nodes/parsenodes.h
***************
*** 1972,1977 **** typedef struct IndexStmt
--- 1972,1978 ----
  	bool		deferrable;		/* is the constraint DEFERRABLE? */
  	bool		initdeferred;	/* is the constraint INITIALLY DEFERRED? */
  	bool		concurrent;		/* should this be a concurrent index build? */
+ 	Oid			oldNode;		/* relfilenode of my former self */
  } IndexStmt;
  
  /* ----------------------
*** a/src/test/regress/expected/alter_table.out
--- b/src/test/regress/expected/alter_table.out
***************
*** 1519,1524 **** CREATE TABLE t (
--- 1519,1525 ----
  	document	xml					NOT NULL,
  	strarr		varchar(2)[]		NOT NULL,
  	square		box					NOT NULL,
+ 	EXCLUDE (stamptz WITH =),
  	CHECK (touchy_f(constraint0) < 10)
  );
  NOTICE:  CREATE TABLE / UNIQUE will create implicit index "t_constraint4_key" for table "t"
***************
*** 1541,1546 **** NOTICE:  CREATE TABLE / UNIQUE will create implicit index "t_bits_key" for table
--- 1542,1549 ----
  DEBUG:  Rebuilding index "t_bits_key"
  NOTICE:  CREATE TABLE / UNIQUE will create implicit index "t_network_key" for table "t"
  DEBUG:  Rebuilding index "t_network_key"
+ NOTICE:  CREATE TABLE / EXCLUDE will create implicit index "t_stamptz_excl" for table "t"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  CREATE INDEX ON t (string);
  DEBUG:  Rebuilding index "t_string_idx"
  CREATE INDEX ON t USING hash (string);
***************
*** 1615,1621 **** FROM pg_class WHERE oid = 't'::regclass
  ORDER BY 1;
        relname      | relnamespace | relowner | relam | reltablespace | relhasindex | relisshared | relpersistence | relkind | relnatts | relchecks | relhasoids | relhaspkey | relhasexclusion | relhasrules | relhastriggers | relacl | reloptions 
  -------------------+--------------+----------+-------+---------------+-------------+-------------+----------------+---------+----------+-----------+------------+------------+-----------------+-------------+----------------+--------+------------
!  t                 |         2200 |       10 |     0 |             0 | t           | f           | p              | r       |       18 |         1 | f          | f          | f               | f           | t              |        | 
   t_bits_key        |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_constraint4_key |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_daytime_key     |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
--- 1618,1624 ----
  ORDER BY 1;
        relname      | relnamespace | relowner | relam | reltablespace | relhasindex | relisshared | relpersistence | relkind | relnatts | relchecks | relhasoids | relhaspkey | relhasexclusion | relhasrules | relhastriggers | relacl | reloptions 
  -------------------+--------------+----------+-------+---------------+-------------+-------------+----------------+---------+----------+-----------+------------+------------+-----------------+-------------+----------------+--------+------------
!  t                 |         2200 |       10 |     0 |             0 | t           | f           | p              | r       |       18 |         1 | f          | f          | t               | f           | t              |        | 
   t_bits_key        |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_constraint4_key |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_daytime_key     |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
***************
*** 1626,1638 **** ORDER BY 1;
   t_rational_key    |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_square_idx      |         2200 |       10 |   783 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_stamp_key       |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_stamptz_key     |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_strarr_idx      |         2200 |       10 |  2742 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_string_idx      |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_string_idx1     |         2200 |       10 |   405 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_timegap_key     |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_touchy_f_idx    |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
! (17 rows)
  
  SELECT	relname, indnatts, indisunique, indisprimary, indimmediate,
  		indisclustered, indisvalid, indcheckxmin, indisready, indkey, indclass,
--- 1629,1642 ----
   t_rational_key    |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_square_idx      |         2200 |       10 |   783 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_stamp_key       |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
+  t_stamptz_excl    |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | t               | f           | f              |        | 
   t_stamptz_key     |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_strarr_idx      |         2200 |       10 |  2742 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_string_idx      |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_string_idx1     |         2200 |       10 |   405 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_timegap_key     |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_touchy_f_idx    |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
! (18 rows)
  
  SELECT	relname, indnatts, indisunique, indisprimary, indimmediate,
  		indisclustered, indisvalid, indcheckxmin, indisready, indkey, indclass,
***************
*** 1651,1663 **** WHERE indrelid = 't'::regclass ORDER BY 1;
   t_rational_key    |        1 | t           | f            | t            | f              | t          | f            | t          | 7      | 10037    | 0
   t_square_idx      |        1 | f           | f            | t            | f              | t          | f            | t          | 18     | 10074    | 0
   t_stamp_key       |        1 | t           | f            | t            | f              | t          | f            | t          | 12     | 10054    | 0
   t_stamptz_key     |        1 | t           | f            | t            | f              | t          | f            | t          | 11     | 10047    | 0
   t_strarr_idx      |        1 | f           | f            | t            | f              | t          | f            | t          | 17     | 10103    | 0
   t_string_idx      |        1 | f           | f            | t            | f              | t          | f            | t          | 8      | 10043    | 0
   t_string_idx1     |        1 | f           | f            | t            | f              | t          | f            | t          | 8      | 10044    | 0
   t_timegap_key     |        1 | t           | f            | t            | f              | t          | f            | t          | 13     | 10031    | 0
   t_touchy_f_idx    |        1 | t           | f            | t            | f              | t          | f            | t          | 0      | 1978     | 0
! (16 rows)
  
  SELECT	relname, attname, atttypid, attstattarget, attlen, attnum, attndims,
  		attcacheoff, atttypmod, attbyval, attstorage, attalign, attnotnull,
--- 1655,1668 ----
   t_rational_key    |        1 | t           | f            | t            | f              | t          | f            | t          | 7      | 10037    | 0
   t_square_idx      |        1 | f           | f            | t            | f              | t          | f            | t          | 18     | 10074    | 0
   t_stamp_key       |        1 | t           | f            | t            | f              | t          | f            | t          | 12     | 10054    | 0
+  t_stamptz_excl    |        1 | f           | f            | t            | f              | t          | f            | t          | 11     | 10047    | 0
   t_stamptz_key     |        1 | t           | f            | t            | f              | t          | f            | t          | 11     | 10047    | 0
   t_strarr_idx      |        1 | f           | f            | t            | f              | t          | f            | t          | 17     | 10103    | 0
   t_string_idx      |        1 | f           | f            | t            | f              | t          | f            | t          | 8      | 10043    | 0
   t_string_idx1     |        1 | f           | f            | t            | f              | t          | f            | t          | 8      | 10044    | 0
   t_timegap_key     |        1 | t           | f            | t            | f              | t          | f            | t          | 13     | 10031    | 0
   t_touchy_f_idx    |        1 | t           | f            | t            | f              | t          | f            | t          | 0      | 1978     | 0
! (17 rows)
  
  SELECT	relname, attname, atttypid, attstattarget, attlen, attnum, attndims,
  		attcacheoff, atttypmod, attbyval, attstorage, attalign, attnotnull,
***************
*** 1702,1714 **** ORDER BY 1, 2;
   t_rational_key    | rational    |     1700 |            -1 |     -1 |      1 |        0 |          -1 |        -1 | f        | m          | i        | f          | f         | f            | t          |           0 |        | 
   t_square_idx      | square      |      603 |            -1 |     32 |      1 |        0 |          -1 |        -1 | f        | p          | d        | f          | f         | f            | t          |           0 |        | 
   t_stamp_key       | stamp       |     1114 |            -1 |      8 |      1 |        0 |          -1 |        -1 | t        | p          | d        | f          | f         | f            | t          |           0 |        | 
   t_stamptz_key     | stamptz     |     1184 |            -1 |      8 |      1 |        0 |          -1 |        -1 | t        | p          | d        | f          | f         | f            | t          |           0 |        | 
   t_strarr_idx      | strarr      |     1043 |            -1 |     -1 |      1 |        1 |          -1 |        -1 | f        | x          | i        | f          | f         | f            | t          |           0 |        | 
   t_string_idx      | string      |     1043 |            -1 |     -1 |      1 |        0 |          -1 |         6 | f        | x          | i        | f          | f         | f            | t          |           0 |        | 
   t_string_idx1     | string      |       23 |            -1 |      4 |      1 |        0 |          -1 |        -1 | t        | p          | i        | f          | f         | f            | t          |           0 |        | 
   t_timegap_key     | timegap     |     1186 |            -1 |     16 |      1 |        0 |          -1 |        -1 | f        | p          | d        | f          | f         | f            | t          |           0 |        | 
   t_touchy_f_idx    | touchy_f    |       23 |            -1 |      4 |      1 |        0 |          -1 |        -1 | t        | p          | i        | f          | f         | f            | t          |           0 |        | 
! (40 rows)
  
  SELECT	conname, connamespace, contype, condeferrable, condeferred, confupdtype,
  		confdeltype, confmatchtype, conislocal, coninhcount, conkey, confkey,
--- 1707,1720 ----
   t_rational_key    | rational    |     1700 |            -1 |     -1 |      1 |        0 |          -1 |        -1 | f        | m          | i        | f          | f         | f            | t          |           0 |        | 
   t_square_idx      | square      |      603 |            -1 |     32 |      1 |        0 |          -1 |        -1 | f        | p          | d        | f          | f         | f            | t          |           0 |        | 
   t_stamp_key       | stamp       |     1114 |            -1 |      8 |      1 |        0 |          -1 |        -1 | t        | p          | d        | f          | f         | f            | t          |           0 |        | 
+  t_stamptz_excl    | stamptz     |     1184 |            -1 |      8 |      1 |        0 |          -1 |        -1 | t        | p          | d        | f          | f         | f            | t          |           0 |        | 
   t_stamptz_key     | stamptz     |     1184 |            -1 |      8 |      1 |        0 |          -1 |        -1 | t        | p          | d        | f          | f         | f            | t          |           0 |        | 
   t_strarr_idx      | strarr      |     1043 |            -1 |     -1 |      1 |        1 |          -1 |        -1 | f        | x          | i        | f          | f         | f            | t          |           0 |        | 
   t_string_idx      | string      |     1043 |            -1 |     -1 |      1 |        0 |          -1 |         6 | f        | x          | i        | f          | f         | f            | t          |           0 |        | 
   t_string_idx1     | string      |       23 |            -1 |      4 |      1 |        0 |          -1 |        -1 | t        | p          | i        | f          | f         | f            | t          |           0 |        | 
   t_timegap_key     | timegap     |     1186 |            -1 |     16 |      1 |        0 |          -1 |        -1 | f        | p          | d        | f          | f         | f            | t          |           0 |        | 
   t_touchy_f_idx    | touchy_f    |       23 |            -1 |      4 |      1 |        0 |          -1 |        -1 | t        | p          | i        | f          | f         | f            | t          |           0 |        | 
! (41 rows)
  
  SELECT	conname, connamespace, contype, condeferrable, condeferred, confupdtype,
  		confdeltype, confmatchtype, conislocal, coninhcount, conkey, confkey,
***************
*** 1727,1735 **** ORDER BY 1;
   t_network_key       |         2200 | u       | f             | f           |             |             |               | t          |           0 | {15}   |         |           |           |           |           | 
   t_rational_key      |         2200 | u       | f             | f           |             |             |               | t          |           0 | {7}    |         |           |           |           |           | 
   t_stamp_key         |         2200 | u       | f             | f           |             |             |               | t          |           0 | {12}   |         |           |           |           |           | 
   t_stamptz_key       |         2200 | u       | f             | f           |             |             |               | t          |           0 | {11}   |         |           |           |           |           | 
   t_timegap_key       |         2200 | u       | f             | f           |             |             |               | t          |           0 | {13}   |         |           |           |           |           | 
! (12 rows)
  
  -- RI trigger names include the table OID.  We don't have a great sort order
  -- available, but tgname probably serves acceptably in practice.
--- 1733,1742 ----
   t_network_key       |         2200 | u       | f             | f           |             |             |               | t          |           0 | {15}   |         |           |           |           |           | 
   t_rational_key      |         2200 | u       | f             | f           |             |             |               | t          |           0 | {7}    |         |           |           |           |           | 
   t_stamp_key         |         2200 | u       | f             | f           |             |             |               | t          |           0 | {12}   |         |           |           |           |           | 
+  t_stamptz_excl      |         2200 | x       | f             | f           |             |             |               | t          |           0 | {11}   |         |           |           |           | {1320}    | 
   t_stamptz_key       |         2200 | u       | f             | f           |             |             |               | t          |           0 | {11}   |         |           |           |           |           | 
   t_timegap_key       |         2200 | u       | f             | f           |             |             |               | t          |           0 | {13}   |         |           |           |           |           | 
! (13 rows)
  
  -- RI trigger names include the table OID.  We don't have a great sort order
  -- available, but tgname probably serves acceptably in practice.
***************
*** 1775,1780 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 1782,1788 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_string_idx1"
  DEBUG:  Rebuilding index "t_strarr_idx"
***************
*** 1796,1801 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 1804,1810 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_string_idx1"
  DEBUG:  Rebuilding index "t_strarr_idx"
***************
*** 1805,1813 **** DEBUG:  Rebuilding index "t_expr_idx"
  DEBUG:  Validating foreign key constraint "t_constraint3_fkey"
  ALTER TABLE t ALTER constraint3 TYPE numeric(7,2); -- verify; FK noop
  DEBUG:  Verifying table "t"
- DEBUG:  Validating foreign key constraint "t_constraint3_fkey"
  ALTER TABLE t ALTER constraint3 TYPE numeric(9,2); -- noop; FK noop
- DEBUG:  Validating foreign key constraint "t_constraint3_fkey"
  -- Change a column with an incoming foreign key constraint.
  ALTER TABLE t ALTER constraint4 TYPE numeric(8,1); -- rewrite; FK error
  DEBUG:  Rewriting table "t"
--- 1814,1820 ----
***************
*** 1820,1825 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 1827,1833 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_string_idx1"
  DEBUG:  Rebuilding index "t_strarr_idx"
***************
*** 1841,1846 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 1849,1855 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_string_idx1"
  DEBUG:  Rebuilding index "t_strarr_idx"
***************
*** 1850,1868 **** DEBUG:  Rebuilding index "t_expr_idx"
  DEBUG:  Rebuilding index "t_constraint4_key"
  DEBUG:  Validating foreign key constraint "child_keycol_fkey"
  ALTER TABLE t ALTER constraint4 TYPE numeric(7,2); -- verify; FK noop
- DEBUG:  Rebuilding index "t_constraint4_key"
  DEBUG:  Verifying table "t"
- DEBUG:  Validating foreign key constraint "child_keycol_fkey"
  ALTER TABLE t ALTER constraint4 TYPE numeric(9,2); -- noop; FK noop
- DEBUG:  Rebuilding index "t_constraint4_key"
- DEBUG:  Validating foreign key constraint "child_keycol_fkey"
  -- Type-specific tests.
  ALTER TABLE t ALTER integral TYPE abstime USING integral::abstime;	-- noop
  DEBUG:  Rebuilding index "t_integral_key"
  ALTER TABLE t ALTER integral TYPE oid USING integral::int4;			-- noop
  DEBUG:  Rebuilding index "t_integral_key"
  ALTER TABLE t ALTER integral TYPE regtype;							-- noop
- DEBUG:  Rebuilding index "t_integral_key"
  ALTER TABLE t ALTER integral TYPE int8;								-- rewrite
  DEBUG:  Rewriting table "t"
  DEBUG:  Rebuilding index "t_rational_key"
--- 1859,1872 ----
***************
*** 1873,1878 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 1877,1883 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_string_idx1"
  DEBUG:  Rebuilding index "t_strarr_idx"
***************
*** 1891,1896 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 1896,1902 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_string_idx1"
  DEBUG:  Rebuilding index "t_strarr_idx"
***************
*** 1908,1913 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 1914,1920 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_string_idx1"
  DEBUG:  Rebuilding index "t_strarr_idx"
***************
*** 1926,1931 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 1933,1939 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_string_idx1"
  DEBUG:  Rebuilding index "t_strarr_idx"
***************
*** 1936,1947 **** DEBUG:  Rebuilding index "t_constraint4_key"
  DEBUG:  Rebuilding index "t_integral_key"
  DEBUG:  Rebuilding index "t_rational_key"
  ALTER TABLE t ALTER rational TYPE numeric(13,4);					-- noop
- DEBUG:  Rebuilding index "t_rational_key"
  ALTER TABLE t ALTER rational TYPE numeric(11,4);					-- verify
- DEBUG:  Rebuilding index "t_rational_key"
  DEBUG:  Verifying table "t"
  ALTER TABLE t ALTER rational TYPE numeric;							-- noop
- DEBUG:  Rebuilding index "t_rational_key"
  ALTER TABLE t ALTER rational TYPE numeric(5,4);						-- verify-e
  DEBUG:  Rewriting table "t"
  ERROR:  numeric field overflow
--- 1944,1952 ----
***************
*** 1951,1979 **** DEBUG:  Rewriting table "t"
  ERROR:  numeric field overflow
  DETAIL:  A field with precision 4, scale 3 must round to an absolute value less than 10^1.
  ALTER TABLE t ALTER string TYPE varchar(4);							-- noop
- DEBUG:  Rebuilding index "t_string_idx1"
- DEBUG:  Rebuilding index "t_string_idx"
  ALTER TABLE t ALTER string TYPE lendom;								-- noop
- DEBUG:  Rebuilding index "t_string_idx"
- DEBUG:  Rebuilding index "t_string_idx1"
  ALTER TABLE t ALTER string TYPE shortdom;							-- rewrite-e
  DEBUG:  Rewriting table "t"
  ERROR:  value too long for type character varying(1)
  ALTER TABLE t ALTER string TYPE checkdom;							-- verify
- DEBUG:  Rebuilding index "t_string_idx1"
- DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Verifying table "t"
  ALTER TABLE t ALTER string TYPE faildom;							-- verify-e
- DEBUG:  Rebuilding index "t_string_idx"
- DEBUG:  Rebuilding index "t_string_idx1"
  DEBUG:  Verifying table "t"
  ERROR:  value for domain faildom violates check constraint "faildom_check"
  ALTER TABLE t ALTER string TYPE loosedom;							-- noop
- DEBUG:  Rebuilding index "t_string_idx"
- DEBUG:  Rebuilding index "t_string_idx1"
  ALTER TABLE t ALTER string TYPE text;								-- noop
- DEBUG:  Rebuilding index "t_string_idx1"
- DEBUG:  Rebuilding index "t_string_idx"
  ALTER TABLE t ALTER string TYPE varchar(20);						-- rewrite-v
  DEBUG:  Rewriting table "t"
  DEBUG:  Rebuilding index "t_daytimetz_key"
--- 1956,1972 ----
***************
*** 1983,1988 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 1976,1982 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_strarr_idx"
  DEBUG:  Rebuilding index "t_square_idx"
  DEBUG:  Rebuilding index "t_touchy_f_idx"
***************
*** 2004,2009 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 1998,2004 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_strarr_idx"
  DEBUG:  Rebuilding index "t_square_idx"
  DEBUG:  Rebuilding index "t_touchy_f_idx"
***************
*** 2022,2027 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 2017,2023 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_strarr_idx"
  DEBUG:  Rebuilding index "t_square_idx"
  DEBUG:  Rebuilding index "t_touchy_f_idx"
***************
*** 2040,2045 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 2036,2042 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_strarr_idx"
  DEBUG:  Rebuilding index "t_square_idx"
  DEBUG:  Rebuilding index "t_touchy_f_idx"
***************
*** 2061,2066 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 2058,2064 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_strarr_idx"
  DEBUG:  Rebuilding index "t_square_idx"
  DEBUG:  Rebuilding index "t_touchy_f_idx"
***************
*** 2079,2084 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 2077,2083 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_strarr_idx"
  DEBUG:  Rebuilding index "t_square_idx"
  DEBUG:  Rebuilding index "t_touchy_f_idx"
***************
*** 2096,2101 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 2095,2101 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_strarr_idx"
  DEBUG:  Rebuilding index "t_square_idx"
  DEBUG:  Rebuilding index "t_touchy_f_idx"
***************
*** 2114,2119 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 2114,2120 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_strarr_idx"
  DEBUG:  Rebuilding index "t_square_idx"
  DEBUG:  Rebuilding index "t_touchy_f_idx"
***************
*** 2125,2131 **** DEBUG:  Rebuilding index "t_string_idx1"
  DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_daytimetz_key"
  ALTER TABLE t ALTER daytimetz TYPE timetz(2);						-- noop
- DEBUG:  Rebuilding index "t_daytimetz_key"
  ALTER TABLE t ALTER daytimetz TYPE time;							-- rewrite
  DEBUG:  Rewriting table "t"
  DEBUG:  Rebuilding index "t_daytime_key"
--- 2126,2131 ----
***************
*** 2134,2139 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 2134,2140 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_strarr_idx"
  DEBUG:  Rebuilding index "t_square_idx"
  DEBUG:  Rebuilding index "t_touchy_f_idx"
***************
*** 2151,2156 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 2152,2158 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_strarr_idx"
  DEBUG:  Rebuilding index "t_square_idx"
  DEBUG:  Rebuilding index "t_touchy_f_idx"
***************
*** 2169,2174 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 2171,2177 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_strarr_idx"
  DEBUG:  Rebuilding index "t_square_idx"
  DEBUG:  Rebuilding index "t_touchy_f_idx"
***************
*** 2181,2187 **** DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  ALTER TABLE t ALTER daytime TYPE time(2);							-- noop
- DEBUG:  Rebuilding index "t_daytime_key"
  ALTER TABLE t ALTER daytime TYPE timetz;							-- rewrite
  DEBUG:  Rewriting table "t"
  DEBUG:  Rebuilding index "t_stamptz_key"
--- 2184,2189 ----
***************
*** 2189,2194 **** DEBUG:  Rebuilding index "t_stamp_key"
--- 2191,2197 ----
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Rebuilding index "t_network_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_strarr_idx"
  DEBUG:  Rebuilding index "t_square_idx"
  DEBUG:  Rebuilding index "t_touchy_f_idx"
***************
*** 2217,2222 **** DEBUG:  Rebuilding index "t_string_idx1"
--- 2220,2226 ----
  DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamptz_key"
  ALTER TABLE t ALTER stamptz TYPE timestamptz(1);					-- rewrite
  DEBUG:  Rewriting table "t"
***************
*** 2236,2245 **** DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
  ALTER TABLE t ALTER stamptz TYPE timestamptz(2);					-- noop
- DEBUG:  Rebuilding index "t_stamptz_key"
  ALTER TABLE t ALTER stamptz TYPE timestamp;							-- noop
- DEBUG:  Rebuilding index "t_stamptz_key"
  SET timezone = 'Asia/Jakarta';
  ALTER TABLE t ALTER stamptz TYPE timestamptz;						-- rewrite
  DEBUG:  Rewriting table "t"
--- 2240,2248 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  ALTER TABLE t ALTER stamptz TYPE timestamptz(2);					-- noop
  ALTER TABLE t ALTER stamptz TYPE timestamp;							-- noop
  SET timezone = 'Asia/Jakarta';
  ALTER TABLE t ALTER stamptz TYPE timestamptz;						-- rewrite
  DEBUG:  Rewriting table "t"
***************
*** 2258,2265 **** DEBUG:  Rebuilding index "t_string_idx1"
--- 2261,2270 ----
  DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamptz_key"
  SET timezone = 'UTC';
+ ALTER TABLE t ALTER stamptz TYPE timestamp;							-- noop
  ALTER TABLE t ALTER stamp TYPE timestamp(3);						-- rewrite-v
  DEBUG:  Rewriting table "t"
  DEBUG:  Rebuilding index "t_timegap_key"
***************
*** 2277,2282 **** DEBUG:  Rebuilding index "t_string_idx"
--- 2282,2288 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamp_key"
  ALTER TABLE t ALTER stamp TYPE timestamp(1);						-- rewrite
  DEBUG:  Rewriting table "t"
***************
*** 2295,2305 **** DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
  DEBUG:  Rebuilding index "t_stamp_key"
  ALTER TABLE t ALTER stamp TYPE timestamp(2);						-- noop
- DEBUG:  Rebuilding index "t_stamp_key"
  ALTER TABLE t ALTER stamp TYPE timestamptz;							-- noop
- DEBUG:  Rebuilding index "t_stamp_key"
  SET timezone = 'Asia/Jakarta';
  ALTER TABLE t ALTER stamp TYPE timestamp;							-- rewrite
  DEBUG:  Rewriting table "t"
--- 2301,2310 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamp_key"
  ALTER TABLE t ALTER stamp TYPE timestamp(2);						-- noop
  ALTER TABLE t ALTER stamp TYPE timestamptz;							-- noop
  SET timezone = 'Asia/Jakarta';
  ALTER TABLE t ALTER stamp TYPE timestamp;							-- rewrite
  DEBUG:  Rewriting table "t"
***************
*** 2318,2325 **** DEBUG:  Rebuilding index "t_string_idx"
--- 2323,2332 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamp_key"
  SET timezone = 'UTC';
+ ALTER TABLE t ALTER stamp TYPE timestamptz;							-- noop
  ALTER TABLE t ALTER timegap TYPE interval(3);						-- rewrite-v
  DEBUG:  Rewriting table "t"
  DEBUG:  Rebuilding index "t_bits_key"
***************
*** 2336,2341 **** DEBUG:  Rebuilding index "t_string_idx"
--- 2343,2349 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamp_key"
  DEBUG:  Rebuilding index "t_timegap_key"
  ALTER TABLE t ALTER timegap TYPE interval(1);						-- rewrite
***************
*** 2354,2368 **** DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
  DEBUG:  Rebuilding index "t_stamp_key"
  DEBUG:  Rebuilding index "t_timegap_key"
  ALTER TABLE t ALTER timegap TYPE interval(2);						-- noop
- DEBUG:  Rebuilding index "t_timegap_key"
  ALTER TABLE t ALTER bits TYPE bit(6);								-- verify
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Verifying table "t"
  ALTER TABLE t ALTER bits TYPE bit(7);								-- verify-e
- DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Verifying table "t"
  ERROR:  bit string length 6 does not match type bit(7)
  ALTER TABLE t ALTER bits TYPE bit(7) USING bits::bit(7);			-- rewrite
--- 2362,2375 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamp_key"
  DEBUG:  Rebuilding index "t_timegap_key"
  ALTER TABLE t ALTER timegap TYPE interval(2);						-- noop
  ALTER TABLE t ALTER bits TYPE bit(6);								-- verify
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Verifying table "t"
  ALTER TABLE t ALTER bits TYPE bit(7);								-- verify-e
  DEBUG:  Verifying table "t"
  ERROR:  bit string length 6 does not match type bit(7)
  ALTER TABLE t ALTER bits TYPE bit(7) USING bits::bit(7);			-- rewrite
***************
*** 2380,2385 **** DEBUG:  Rebuilding index "t_string_idx"
--- 2387,2393 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamp_key"
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
***************
*** 2388,2397 **** ALTER TABLE t ALTER bits TYPE varbit(8);							-- verify
  DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Verifying table "t"
  ALTER TABLE t ALTER bits TYPE varbit(7);							-- verify
- DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Verifying table "t"
  ALTER TABLE t ALTER bits TYPE varbit(5);							-- verify-e
- DEBUG:  Rebuilding index "t_bits_key"
  DEBUG:  Verifying table "t"
  ERROR:  bit string too long for type bit varying(5)
  ALTER TABLE t ALTER bits TYPE varbit(5) USING bits::varbit(5);		-- rewrite
--- 2396,2403 ----
***************
*** 2409,2421 **** DEBUG:  Rebuilding index "t_string_idx"
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
  DEBUG:  Rebuilding index "t_stamp_key"
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  ALTER TABLE t ALTER bits TYPE varbit(8);							-- noop
- DEBUG:  Rebuilding index "t_bits_key"
  ALTER TABLE t ALTER network TYPE inet;								-- noop
- DEBUG:  Rebuilding index "t_network_key"
  ALTER TABLE t ALTER network TYPE cidr;								-- rewrite-v
  DEBUG:  Rewriting table "t"
  DEBUG:  Rebuilding index "t_strarr_idx"
--- 2415,2426 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamp_key"
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
  ALTER TABLE t ALTER bits TYPE varbit(8);							-- noop
  ALTER TABLE t ALTER network TYPE inet;								-- noop
  ALTER TABLE t ALTER network TYPE cidr;								-- rewrite-v
  DEBUG:  Rewriting table "t"
  DEBUG:  Rebuilding index "t_strarr_idx"
***************
*** 2430,2435 **** DEBUG:  Rebuilding index "t_string_idx"
--- 2435,2441 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamp_key"
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
***************
*** 2451,2456 **** DEBUG:  Rebuilding index "t_string_idx"
--- 2457,2463 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamp_key"
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
***************
*** 2471,2476 **** DEBUG:  Rebuilding index "t_string_idx"
--- 2478,2484 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamp_key"
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
***************
*** 2478,2484 **** DEBUG:  Rebuilding index "t_network_key"
  ALTER TABLE t ALTER document TYPE xml USING document::xml;			-- verify
  DEBUG:  Verifying table "t"
  ALTER TABLE t ALTER strarr TYPE varchar(4)[];						-- noop
- DEBUG:  Rebuilding index "t_strarr_idx"
  ALTER TABLE t ALTER strarr TYPE varchar(3)[];						-- rewrite-v
  DEBUG:  Rewriting table "t"
  DEBUG:  Rebuilding index "t_square_idx"
--- 2486,2491 ----
***************
*** 2492,2497 **** DEBUG:  Rebuilding index "t_string_idx"
--- 2499,2505 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamp_key"
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
***************
*** 2513,2518 **** DEBUG:  Rebuilding index "t_string_idx"
--- 2521,2527 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamp_key"
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
***************
*** 2530,2535 **** DEBUG:  Rebuilding index "t_string_idx"
--- 2539,2545 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamp_key"
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
***************
*** 2552,2557 **** DEBUG:  Rebuilding index "t_string_idx"
--- 2562,2568 ----
  DEBUG:  Rebuilding index "t_daytimetz_key"
  DEBUG:  Rebuilding index "t_daytime_key"
  DEBUG:  Rebuilding index "t_stamptz_key"
+ DEBUG:  Rebuilding index "t_stamptz_excl"
  DEBUG:  Rebuilding index "t_stamp_key"
  DEBUG:  Rebuilding index "t_timegap_key"
  DEBUG:  Rebuilding index "t_bits_key"
***************
*** 2563,2572 **** DEBUG:  Rebuilding index "t_integral_key"
  DEBUG:  Rebuilding index "u1"
  -- Data and catalog end state.  We omit the columns that bear unstable OIDs.
  SELECT * FROM t ORDER BY 1;
!  constraint0 | constraint1 | constraint2 | constraint3 | constraint4 | integral | rational | string | daytimetz  |    daytime    |            stamptz             |           stamp            |  timegap   | bits  |   network   |       document       | strarr  |          square           
! -------------+-------------+-------------+-------------+-------------+----------+----------+--------+------------+---------------+--------------------------------+----------------------------+------------+-------+-------------+----------------------+---------+---------------------------
!            1 |           2 |           3 |        1.05 |        1.06 |        4 |  10.1200 | fo     | 08:44:00.2 | 08:44:00.3+00 | Sat Jan 01 01:44:00.4 2000 UTC | Sat Jan 01 15:44:00.5 2000 | @ 1.6 secs | 01110 | 10.0.0.0/16 | <foo/>               | {ab,cd} | ((0,0),(0,1),(1,1),(1,0))
!            2 |           3 |           4 |        1.15 |        1.16 |        5 |  11.1200 | fo     | 09:44:00.2 | 09:44:00.3+00 | Sat Jan 01 02:44:00.4 2000 UTC | Sat Jan 01 16:44:00.5 2000 | @ 2.6 secs | 00110 | 10.1.0.0/16 | <bar/>               | {ef,gh} | ((0,0),(0,2),(2,2),(2,0))
  (2 rows)
  
  SELECT	relname, relnamespace, relowner, relam, reltablespace, relhasindex,
--- 2574,2583 ----
  DEBUG:  Rebuilding index "u1"
  -- Data and catalog end state.  We omit the columns that bear unstable OIDs.
  SELECT * FROM t ORDER BY 1;
!  constraint0 | constraint1 | constraint2 | constraint3 | constraint4 | integral | rational | string | daytimetz  |    daytime    |          stamptz           |             stamp              |  timegap   | bits  |   network   |       document       | strarr  |          square           
! -------------+-------------+-------------+-------------+-------------+----------+----------+--------+------------+---------------+----------------------------+--------------------------------+------------+-------+-------------+----------------------+---------+---------------------------
!            1 |           2 |           3 |        1.05 |        1.06 |        4 |  10.1200 | fo     | 08:44:00.2 | 08:44:00.3+00 | Sat Jan 01 01:44:00.4 2000 | Sat Jan 01 15:44:00.5 2000 UTC | @ 1.6 secs | 01110 | 10.0.0.0/16 | <foo/>               | {ab,cd} | ((0,0),(0,1),(1,1),(1,0))
!            2 |           3 |           4 |        1.15 |        1.16 |        5 |  11.1200 | fo     | 09:44:00.2 | 09:44:00.3+00 | Sat Jan 01 02:44:00.4 2000 | Sat Jan 01 16:44:00.5 2000 UTC | @ 2.6 secs | 00110 | 10.1.0.0/16 | <bar/>               | {ef,gh} | ((0,0),(0,2),(2,2),(2,0))
  (2 rows)
  
  SELECT	relname, relnamespace, relowner, relam, reltablespace, relhasindex,
***************
*** 2578,2584 **** FROM pg_class WHERE oid = 't'::regclass
  ORDER BY 1;
        relname      | relnamespace | relowner | relam | reltablespace | relhasindex | relisshared | relpersistence | relkind | relnatts | relchecks | relhasoids | relhaspkey | relhasexclusion | relhasrules | relhastriggers | relacl | reloptions 
  -------------------+--------------+----------+-------+---------------+-------------+-------------+----------------+---------+----------+-----------+------------+------------+-----------------+-------------+----------------+--------+------------
!  t                 |         2200 |       10 |     0 |             0 | t           | f           | p              | r       |       18 |         1 | f          | f          | f               | f           | t              |        | 
   t_bits_key        |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_constraint4_key |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_daytime_key     |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
--- 2589,2595 ----
  ORDER BY 1;
        relname      | relnamespace | relowner | relam | reltablespace | relhasindex | relisshared | relpersistence | relkind | relnatts | relchecks | relhasoids | relhaspkey | relhasexclusion | relhasrules | relhastriggers | relacl | reloptions 
  -------------------+--------------+----------+-------+---------------+-------------+-------------+----------------+---------+----------+-----------+------------+------------+-----------------+-------------+----------------+--------+------------
!  t                 |         2200 |       10 |     0 |             0 | t           | f           | p              | r       |       18 |         1 | f          | f          | t               | f           | t              |        | 
   t_bits_key        |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_constraint4_key |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_daytime_key     |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
***************
*** 2589,2594 **** ORDER BY 1;
--- 2600,2606 ----
   t_rational_key    |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_square_idx      |         2200 |       10 |   783 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_stamp_key       |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
+  t_stamptz_excl    |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | t               | f           | f              |        | 
   t_stamptz_key     |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_strarr_idx      |         2200 |       10 |  2742 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   t_string_idx      |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
***************
*** 2597,2603 **** ORDER BY 1;
   t_touchy_f_idx    |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   u0                |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   u1                |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
! (19 rows)
  
  SELECT	relname, indnatts, indisunique, indisprimary, indimmediate,
  		indisclustered, indisvalid, indcheckxmin, indisready, indkey, indclass,
--- 2609,2615 ----
   t_touchy_f_idx    |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   u0                |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
   u1                |         2200 |       10 |   403 |             0 | f           | f           | p              | i       |        1 |         0 | f          | f          | f               | f           | f              |        | 
! (20 rows)
  
  SELECT	relname, indnatts, indisunique, indisprimary, indimmediate,
  		indisclustered, indisvalid, indcheckxmin, indisready, indkey, indclass,
***************
*** 2615,2622 **** WHERE indrelid = 't'::regclass ORDER BY 1;
   t_network_key     |        1 | t           | f            | t            | f              | t          | f            | t          | 15     | 10025    | 0
   t_rational_key    |        1 | t           | f            | t            | f              | t          | f            | t          | 7      | 10037    | 0
   t_square_idx      |        1 | f           | f            | t            | f              | t          | f            | t          | 18     | 10076    | 0
!  t_stamp_key       |        1 | t           | f            | t            | f              | t          | f            | t          | 12     | 10054    | 0
!  t_stamptz_key     |        1 | t           | f            | t            | f              | t          | f            | t          | 11     | 10047    | 0
   t_strarr_idx      |        1 | f           | f            | t            | f              | t          | f            | t          | 17     | 10079    | 0
   t_string_idx      |        1 | f           | f            | t            | f              | t          | f            | t          | 8      | 10012    | 0
   t_string_idx1     |        1 | f           | f            | t            | f              | t          | f            | t          | 8      | 10013    | 0
--- 2627,2635 ----
   t_network_key     |        1 | t           | f            | t            | f              | t          | f            | t          | 15     | 10025    | 0
   t_rational_key    |        1 | t           | f            | t            | f              | t          | f            | t          | 7      | 10037    | 0
   t_square_idx      |        1 | f           | f            | t            | f              | t          | f            | t          | 18     | 10076    | 0
!  t_stamp_key       |        1 | t           | f            | t            | f              | t          | f            | t          | 12     | 10047    | 0
!  t_stamptz_excl    |        1 | f           | f            | t            | f              | t          | f            | t          | 11     | 10054    | 0
!  t_stamptz_key     |        1 | t           | f            | t            | f              | t          | f            | t          | 11     | 10054    | 0
   t_strarr_idx      |        1 | f           | f            | t            | f              | t          | f            | t          | 17     | 10079    | 0
   t_string_idx      |        1 | f           | f            | t            | f              | t          | f            | t          | 8      | 10012    | 0
   t_string_idx1     |        1 | f           | f            | t            | f              | t          | f            | t          | 8      | 10013    | 0
***************
*** 2624,2630 **** WHERE indrelid = 't'::regclass ORDER BY 1;
   t_touchy_f_idx    |        1 | t           | f            | t            | f              | t          | f            | t          | 0      | 1978     | 0
   u0                |        1 | t           | f            | t            | f              | t          | f            | t          | 6      | 1978     | 0
   u1                |        1 | t           | f            | t            | f              | t          | f            | t          | 6      | 1978     | 0
! (18 rows)
  
  SELECT	relname, attname, atttypid, attstattarget, attlen, attnum, attndims,
  		attcacheoff, atttypmod, attbyval, attstorage, attalign, attnotnull,
--- 2637,2643 ----
   t_touchy_f_idx    |        1 | t           | f            | t            | f              | t          | f            | t          | 0      | 1978     | 0
   u0                |        1 | t           | f            | t            | f              | t          | f            | t          | 6      | 1978     | 0
   u1                |        1 | t           | f            | t            | f              | t          | f            | t          | 6      | 1978     | 0
! (19 rows)
  
  SELECT	relname, attname, atttypid, attstattarget, attlen, attnum, attndims,
  		attcacheoff, atttypmod, attbyval, attstorage, attalign, attnotnull,
***************
*** 2651,2658 **** ORDER BY 1, 2;
   t                 | network     |      650 |            -1 |     -1 |     15 |        0 |          -1 |         -1 | f        | m          | i        | t          | f         | f            | t          |           0 |        | 
   t                 | rational    |     1700 |            -1 |     -1 |      7 |        0 |          -1 |         -1 | f        | m          | i        | t          | f         | f            | t          |           0 |        | 
   t                 | square      |      604 |            -1 |     -1 |     18 |        0 |          -1 |         -1 | f        | x          | d        | t          | f         | f            | t          |           0 |        | 
!  t                 | stamp       |     1114 |            -1 |      8 |     12 |        0 |          -1 |         -1 | t        | p          | d        | t          | f         | f            | t          |           0 |        | 
!  t                 | stamptz     |     1184 |            -1 |      8 |     11 |        0 |          -1 |         -1 | t        | p          | d        | t          | f         | f            | t          |           0 |        | 
   t                 | strarr      |     1009 |            -1 |     -1 |     17 |        1 |          -1 |         -1 | f        | x          | i        | t          | f         | f            | t          |           0 |        | 
   t                 | string      |     1042 |            -1 |     -1 |      8 |        0 |          -1 |          8 | f        | x          | i        | t          | f         | f            | t          |           0 |        | 
   t                 | tableoid    |       26 |             0 |      4 |     -7 |        0 |          -1 |         -1 | t        | p          | i        | t          | f         | f            | t          |           0 |        | 
--- 2664,2671 ----
   t                 | network     |      650 |            -1 |     -1 |     15 |        0 |          -1 |         -1 | f        | m          | i        | t          | f         | f            | t          |           0 |        | 
   t                 | rational    |     1700 |            -1 |     -1 |      7 |        0 |          -1 |         -1 | f        | m          | i        | t          | f         | f            | t          |           0 |        | 
   t                 | square      |      604 |            -1 |     -1 |     18 |        0 |          -1 |         -1 | f        | x          | d        | t          | f         | f            | t          |           0 |        | 
!  t                 | stamp       |     1184 |            -1 |      8 |     12 |        0 |          -1 |         -1 | t        | p          | d        | t          | f         | f            | t          |           0 |        | 
!  t                 | stamptz     |     1114 |            -1 |      8 |     11 |        0 |          -1 |         -1 | t        | p          | d        | t          | f         | f            | t          |           0 |        | 
   t                 | strarr      |     1009 |            -1 |     -1 |     17 |        1 |          -1 |         -1 | f        | x          | i        | t          | f         | f            | t          |           0 |        | 
   t                 | string      |     1042 |            -1 |     -1 |      8 |        0 |          -1 |          8 | f        | x          | i        | t          | f         | f            | t          |           0 |        | 
   t                 | tableoid    |       26 |             0 |      4 |     -7 |        0 |          -1 |         -1 | t        | p          | i        | t          | f         | f            | t          |           0 |        | 
***************
*** 2668,2675 **** ORDER BY 1, 2;
   t_network_key     | network     |      650 |            -1 |     -1 |      1 |        0 |          -1 |         -1 | f        | m          | i        | f          | f         | f            | t          |           0 |        | 
   t_rational_key    | rational    |     1700 |            -1 |     -1 |      1 |        0 |          -1 |         -1 | f        | m          | i        | f          | f         | f            | t          |           0 |        | 
   t_square_idx      | square      |      603 |            -1 |     32 |      1 |        0 |          -1 |         -1 | f        | p          | d        | f          | f         | f            | t          |           0 |        | 
!  t_stamp_key       | stamp       |     1114 |            -1 |      8 |      1 |        0 |          -1 |         -1 | t        | p          | d        | f          | f         | f            | t          |           0 |        | 
!  t_stamptz_key     | stamptz     |     1184 |            -1 |      8 |      1 |        0 |          -1 |         -1 | t        | p          | d        | f          | f         | f            | t          |           0 |        | 
   t_strarr_idx      | strarr      |       25 |            -1 |     -1 |      1 |        1 |          -1 |         -1 | f        | x          | i        | f          | f         | f            | t          |           0 |        | 
   t_string_idx      | string      |     1042 |            -1 |     -1 |      1 |        0 |          -1 |          8 | f        | x          | i        | f          | f         | f            | t          |           0 |        | 
   t_string_idx1     | string      |       23 |            -1 |      4 |      1 |        0 |          -1 |         -1 | t        | p          | i        | f          | f         | f            | t          |           0 |        | 
--- 2681,2689 ----
   t_network_key     | network     |      650 |            -1 |     -1 |      1 |        0 |          -1 |         -1 | f        | m          | i        | f          | f         | f            | t          |           0 |        | 
   t_rational_key    | rational    |     1700 |            -1 |     -1 |      1 |        0 |          -1 |         -1 | f        | m          | i        | f          | f         | f            | t          |           0 |        | 
   t_square_idx      | square      |      603 |            -1 |     32 |      1 |        0 |          -1 |         -1 | f        | p          | d        | f          | f         | f            | t          |           0 |        | 
!  t_stamp_key       | stamp       |     1184 |            -1 |      8 |      1 |        0 |          -1 |         -1 | t        | p          | d        | f          | f         | f            | t          |           0 |        | 
!  t_stamptz_excl    | stamptz     |     1114 |            -1 |      8 |      1 |        0 |          -1 |         -1 | t        | p          | d        | f          | f         | f            | t          |           0 |        | 
!  t_stamptz_key     | stamptz     |     1114 |            -1 |      8 |      1 |        0 |          -1 |         -1 | t        | p          | d        | f          | f         | f            | t          |           0 |        | 
   t_strarr_idx      | strarr      |       25 |            -1 |     -1 |      1 |        1 |          -1 |         -1 | f        | x          | i        | f          | f         | f            | t          |           0 |        | 
   t_string_idx      | string      |     1042 |            -1 |     -1 |      1 |        0 |          -1 |          8 | f        | x          | i        | f          | f         | f            | t          |           0 |        | 
   t_string_idx1     | string      |       23 |            -1 |      4 |      1 |        0 |          -1 |         -1 | t        | p          | i        | f          | f         | f            | t          |           0 |        | 
***************
*** 2677,2683 **** ORDER BY 1, 2;
   t_touchy_f_idx    | touchy_f    |       23 |            -1 |      4 |      1 |        0 |          -1 |         -1 | t        | p          | i        | f          | f         | f            | t          |           0 |        | 
   u0                | integral    |       23 |            -1 |      4 |      1 |        0 |          -1 |         -1 | t        | p          | i        | f          | f         | f            | t          |           0 |        | 
   u1                | integral    |       23 |            -1 |      4 |      1 |        0 |          -1 |         -1 | t        | p          | i        | f          | f         | f            | t          |           0 |        | 
! (42 rows)
  
  SELECT	conname, connamespace, contype, condeferrable, condeferred, confupdtype,
  		confdeltype, confmatchtype, conislocal, coninhcount, conkey, confkey,
--- 2691,2697 ----
   t_touchy_f_idx    | touchy_f    |       23 |            -1 |      4 |      1 |        0 |          -1 |         -1 | t        | p          | i        | f          | f         | f            | t          |           0 |        | 
   u0                | integral    |       23 |            -1 |      4 |      1 |        0 |          -1 |         -1 | t        | p          | i        | f          | f         | f            | t          |           0 |        | 
   u1                | integral    |       23 |            -1 |      4 |      1 |        0 |          -1 |         -1 | t        | p          | i        | f          | f         | f            | t          |           0 |        | 
! (43 rows)
  
  SELECT	conname, connamespace, contype, condeferrable, condeferred, confupdtype,
  		confdeltype, confmatchtype, conislocal, coninhcount, conkey, confkey,
***************
*** 2696,2706 **** ORDER BY 1;
   t_network_key       |         2200 | u       | f             | f           |             |             |               | t          |           0 | {15}   |         |           |           |           |           | 
   t_rational_key      |         2200 | u       | f             | f           |             |             |               | t          |           0 | {7}    |         |           |           |           |           | 
   t_stamp_key         |         2200 | u       | f             | f           |             |             |               | t          |           0 | {12}   |         |           |           |           |           | 
   t_stamptz_key       |         2200 | u       | f             | f           |             |             |               | t          |           0 | {11}   |         |           |           |           |           | 
   t_timegap_key       |         2200 | u       | f             | f           |             |             |               | t          |           0 | {13}   |         |           |           |           |           | 
   u0                  |         2200 | u       | f             | f           |             |             |               | t          |           0 | {6}    |         |           |           |           |           | 
   u1                  |         2200 | u       | f             | f           |             |             |               | t          |           0 | {6}    |         |           |           |           |           | 
! (14 rows)
  
  -- RI trigger names include the table OID.  We don't have a great sort order
  -- available, but tgname probably serves acceptably in practice.
--- 2710,2721 ----
   t_network_key       |         2200 | u       | f             | f           |             |             |               | t          |           0 | {15}   |         |           |           |           |           | 
   t_rational_key      |         2200 | u       | f             | f           |             |             |               | t          |           0 | {7}    |         |           |           |           |           | 
   t_stamp_key         |         2200 | u       | f             | f           |             |             |               | t          |           0 | {12}   |         |           |           |           |           | 
+  t_stamptz_excl      |         2200 | x       | f             | f           |             |             |               | t          |           0 | {11}   |         |           |           |           | {2060}    | 
   t_stamptz_key       |         2200 | u       | f             | f           |             |             |               | t          |           0 | {11}   |         |           |           |           |           | 
   t_timegap_key       |         2200 | u       | f             | f           |             |             |               | t          |           0 | {13}   |         |           |           |           |           | 
   u0                  |         2200 | u       | f             | f           |             |             |               | t          |           0 | {6}    |         |           |           |           |           | 
   u1                  |         2200 | u       | f             | f           |             |             |               | t          |           0 | {6}    |         |           |           |           |           | 
! (15 rows)
  
  -- RI trigger names include the table OID.  We don't have a great sort order
  -- available, but tgname probably serves acceptably in practice.
*** a/src/test/regress/sql/alter_table.sql
--- b/src/test/regress/sql/alter_table.sql
***************
*** 1141,1146 **** CREATE TABLE t (
--- 1141,1147 ----
  	strarr		varchar(2)[]		NOT NULL,
  	square		box					NOT NULL,
  
+ 	EXCLUDE (stamptz WITH =),
  	CHECK (touchy_f(constraint0) < 10)
  );
  CREATE INDEX ON t (string);
***************
*** 1307,1312 **** ALTER TABLE t ALTER stamptz TYPE timestamp;							-- noop
--- 1308,1314 ----
  SET timezone = 'Asia/Jakarta';
  ALTER TABLE t ALTER stamptz TYPE timestamptz;						-- rewrite
  SET timezone = 'UTC';
+ ALTER TABLE t ALTER stamptz TYPE timestamp;							-- noop
  
  ALTER TABLE t ALTER stamp TYPE timestamp(3);						-- rewrite-v
  ALTER TABLE t ALTER stamp TYPE timestamp(1);						-- rewrite
***************
*** 1315,1320 **** ALTER TABLE t ALTER stamp TYPE timestamptz;							-- noop
--- 1317,1323 ----
  SET timezone = 'Asia/Jakarta';
  ALTER TABLE t ALTER stamp TYPE timestamp;							-- rewrite
  SET timezone = 'UTC';
+ ALTER TABLE t ALTER stamp TYPE timestamptz;							-- noop
  
  ALTER TABLE t ALTER timegap TYPE interval(3);						-- rewrite-v
  ALTER TABLE t ALTER timegap TYPE interval(1);						-- rewrite