at0v3-debug-tests.patch

text/plain

Filename: at0v3-debug-tests.patch
Type: text/plain
Part: 0
Message: Re: ALTER TYPE 0: Introduction; test cases

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: unified
File+
index 4895768..8e5090e 100644 0 0
src/backend/catalog/index.c 0 0
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 5790f87..6f5ffb3 100644
*** a/src/backend/catalog/index.c
--- b/src/backend/catalog/index.c
***************
*** 1420,1425 **** index_build(Relation heapRelation,
--- 1420,1435 ----
  	procedure = indexRelation->rd_am->ambuild;
  	Assert(RegProcedureIsValid(procedure));
  
+ 	if (indexInfo->ii_ToastForRelName != NULL)
+ 		ereport(DEBUG1,
+ 				(errmsg("building TOAST index for table \"%s\"",
+ 						indexInfo->ii_ToastForRelName)));
+ 	else
+ 		ereport(DEBUG1,
+ 				(errmsg("building index \"%s\" on table \"%s\"",
+ 						RelationGetRelationName(indexRelation),
+ 						RelationGetRelationName(heapRelation))));
+ 
  	/*
  	 * Switch to the table owner's userid, so that any index functions are run
  	 * as that user.  Also lock down security-restricted operations and
***************
*** 2412,2418 **** IndexGetRelation(Oid indexId)
   * reindex_index - This routine is used to recreate a single index
   */
  void
! reindex_index(Oid indexId, bool skip_constraint_checks)
  {
  	Relation	iRel,
  				heapRelation,
--- 2422,2429 ----
   * reindex_index - This routine is used to recreate a single index
   */
  void
! reindex_index(Oid indexId, const char *toastFor,
! 			  bool skip_constraint_checks)
  {
  	Relation	iRel,
  				heapRelation,
***************
*** 2470,2475 **** reindex_index(Oid indexId, bool skip_constraint_checks)
--- 2481,2489 ----
  			indexInfo->ii_ExclusionStrats = NULL;
  		}
  
+ 		/* Pass the name of relation this TOAST index serves, if any. */
+ 		indexInfo->ii_ToastForRelName = toastFor;
+ 
  		/* We'll build a new physical relation for the index */
  		RelationSetNewRelfilenode(iRel, InvalidTransactionId);
  
***************
*** 2529,2534 **** reindex_index(Oid indexId, bool skip_constraint_checks)
--- 2543,2551 ----
   * reindex_relation - This routine is used to recreate all indexes
   * of a relation (and optionally its toast relation too, if any).
   *
+  * If this is a TOAST relation, toastFor may bear the parent relation name,
+  * facilitating improved messages.
+  *
   * If heap_rebuilt is true, then the relation was just completely rebuilt by
   * an operation such as VACUUM FULL or CLUSTER, and therefore its indexes are
   * inconsistent with it.  This makes things tricky if the relation is a system
***************
*** 2548,2554 **** reindex_index(Oid indexId, bool skip_constraint_checks)
   * CommandCounterIncrement will occur after each index rebuild.
   */
  bool
! reindex_relation(Oid relid, bool toast_too, bool heap_rebuilt)
  {
  	Relation	rel;
  	Oid			toast_relid;
--- 2565,2572 ----
   * CommandCounterIncrement will occur after each index rebuild.
   */
  bool
! reindex_relation(Oid relid, const char *toastFor,
! 				 bool toast_too, bool heap_rebuilt)
  {
  	Relation	rel;
  	Oid			toast_relid;
***************
*** 2625,2631 **** reindex_relation(Oid relid, bool toast_too, bool heap_rebuilt)
  			if (is_pg_class)
  				RelationSetIndexList(rel, doneIndexes, InvalidOid);
  
! 			reindex_index(indexOid, heap_rebuilt);
  
  			CommandCounterIncrement();
  
--- 2643,2649 ----
  			if (is_pg_class)
  				RelationSetIndexList(rel, doneIndexes, InvalidOid);
  
! 			reindex_index(indexOid, toastFor, heap_rebuilt);
  
  			CommandCounterIncrement();
  
***************
*** 2648,2658 **** reindex_relation(Oid relid, bool toast_too, bool heap_rebuilt)
  	if (is_pg_class)
  		RelationSetIndexList(rel, indexIds, ClassOidIndexId);
  
- 	/*
- 	 * Close rel, but continue to hold the lock.
- 	 */
- 	heap_close(rel, NoLock);
- 
  	result = (indexIds != NIL);
  
  	/*
--- 2666,2671 ----
***************
*** 2660,2666 **** reindex_relation(Oid relid, bool toast_too, bool heap_rebuilt)
  	 * still hold the lock on the master table.
  	 */
  	if (toast_too && OidIsValid(toast_relid))
! 		result |= reindex_relation(toast_relid, false, false);
  
  	return result;
  }
--- 2673,2685 ----
  	 * still hold the lock on the master table.
  	 */
  	if (toast_too && OidIsValid(toast_relid))
! 		result |= reindex_relation(toast_relid, RelationGetRelationName(rel),
! 								   false, false);
! 
! 	/*
! 	 * Close rel, but continue to hold the lock.
! 	 */
! 	heap_close(rel, NoLock);
  
  	return result;
  }
diff --git a/src/backend/catalog/tindex 142beae..031471b 100644
*** a/src/backend/catalog/toasting.c
--- b/src/backend/catalog/toasting.c
***************
*** 36,43 **** extern Oid	binary_upgrade_next_toast_pg_class_oid;
  
  Oid			binary_upgrade_next_toast_pg_type_oid = InvalidOid;
  
! static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
! 				   Datum reloptions);
  static bool needs_toast_table(Relation rel);
  
  
--- 36,43 ----
  
  Oid			binary_upgrade_next_toast_pg_type_oid = InvalidOid;
  
! static bool create_toast_table(Relation rel, const char *finalRelName,
! 				   Oid toastOid, Oid toastIndexOid, Datum reloptions);
  static bool needs_toast_table(Relation rel);
  
  
***************
*** 46,51 **** static bool needs_toast_table(Relation rel);
--- 46,54 ----
   *		If the table needs a toast table, and doesn't already have one,
   *		then create a toast table for it.
   *
+  * make_new_heap fills finalRelName, so messages display the permanent table
+  * name, not the rewrite-temporary name.  Most callers should pass NULL.
+  *
   * reloptions for the toast table can be passed, too.  Pass (Datum) 0
   * for default reloptions.
   *
***************
*** 54,60 **** static bool needs_toast_table(Relation rel);
   * to end with CommandCounterIncrement if it makes any changes.
   */
  void
! AlterTableCreateToastTable(Oid relOid, Datum reloptions)
  {
  	Relation	rel;
  
--- 57,64 ----
   * to end with CommandCounterIncrement if it makes any changes.
   */
  void
! AlterTableCreateToastTable(Oid relOid, const char *finalRelName,
! 						   Datum reloptions)
  {
  	Relation	rel;
  
***************
*** 66,72 **** AlterTableCreateToastTable(Oid relOid, Datum reloptions)
  	rel = heap_open(relOid, AccessExclusiveLock);
  
  	/* create_toast_table does all the work */
! 	(void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions);
  
  	heap_close(rel, NoLock);
  }
--- 70,77 ----
  	rel = heap_open(relOid, AccessExclusiveLock);
  
  	/* create_toast_table does all the work */
! 	(void) create_toast_table(rel, finalRelName,
! 							  InvalidOid, InvalidOid, reloptions);
  
  	heap_close(rel, NoLock);
  }
***************
*** 92,98 **** BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid)
  						relName)));
  
  	/* create_toast_table does all the work */
! 	if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0))
  		elog(ERROR, "\"%s\" does not require a toast table",
  			 relName);
  
--- 97,103 ----
  						relName)));
  
  	/* create_toast_table does all the work */
! 	if (!create_toast_table(rel, NULL, toastOid, toastIndexOid, (Datum) 0))
  		elog(ERROR, "\"%s\" does not require a toast table",
  			 relName);
  
***************
*** 104,114 **** BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid)
   * create_toast_table --- internal workhorse
   *
   * rel is already opened and exclusive-locked
   * toastOid and toastIndexOid are normally InvalidOid, but during
   * bootstrap they can be nonzero to specify hand-assigned OIDs
   */
  static bool
! create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptions)
  {
  	Oid			relOid = RelationGetRelid(rel);
  	HeapTuple	reltup;
--- 109,121 ----
   * create_toast_table --- internal workhorse
   *
   * rel is already opened and exclusive-locked
+  * finalRelName is normally NULL; make_new_heap overrides it
   * toastOid and toastIndexOid are normally InvalidOid, but during
   * bootstrap they can be nonzero to specify hand-assigned OIDs
   */
  static bool
! create_toast_table(Relation rel, const char *finalRelName,
! 				   Oid toastOid, Oid toastIndexOid, Datum reloptions)
  {
  	Oid			relOid = RelationGetRelid(rel);
  	HeapTuple	reltup;
***************
*** 255,260 **** create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio
--- 262,269 ----
  	indexInfo->ii_ExclusionOps = NULL;
  	indexInfo->ii_ExclusionProcs = NULL;
  	indexInfo->ii_ExclusionStrats = NULL;
+ 	indexInfo->ii_ToastForRelName
+ 		= finalRelName != NULL ? finalRelName : RelationGetRelationName(rel);
  	indexInfo->ii_Unique = true;
  	indexInfo->ii_ReadyForInserts = true;
  	indexInfo->ii_Concurrent = false;
diff --git a/src/backend/commands/cluindex 19c3cf9..25f5a3d 100644
*** a/src/backend/commands/cluster.c
--- b/src/backend/commands/cluster.c
***************
*** 681,687 **** make_new_heap(Oid OIDOldHeap, Oid NewTableSpace)
  		if (isNull)
  			reloptions = (Datum) 0;
  
! 		AlterTableCreateToastTable(OIDNewHeap, reloptions);
  
  		ReleaseSysCache(tuple);
  	}
--- 681,688 ----
  		if (isNull)
  			reloptions = (Datum) 0;
  
! 		AlterTableCreateToastTable(OIDNewHeap, RelationGetRelationName(OldHeap),
! 								   reloptions);
  
  		ReleaseSysCache(tuple);
  	}
***************
*** 1395,1401 **** finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
  	 * so no chance to reclaim disk space before commit.  We do not need a
  	 * final CommandCounterIncrement() because reindex_relation does it.
  	 */
! 	reindex_relation(OIDOldHeap, false, true);
  
  	/* Destroy new heap with old filenode */
  	object.classId = RelationRelationId;
--- 1396,1402 ----
  	 * so no chance to reclaim disk space before commit.  We do not need a
  	 * final CommandCounterIncrement() because reindex_relation does it.
  	 */
! 	reindex_relation(OIDOldHeap, NULL, false, true);
  
  	/* Destroy new heap with old filenode */
  	object.classId = RelationRelationId;
diff --git a/src/backend/commands/indindex f809a26..b84e2b2 100644
*** a/src/backend/commands/indexcmds.c
--- b/src/backend/commands/indexcmds.c
***************
*** 1597,1603 **** ReindexIndex(RangeVar *indexRelation)
  
  	ReleaseSysCache(tuple);
  
! 	reindex_index(indOid, false);
  }
  
  /*
--- 1597,1603 ----
  
  	ReleaseSysCache(tuple);
  
! 	reindex_index(indOid, NULL, false);
  }
  
  /*
***************
*** 1629,1635 **** ReindexTable(RangeVar *relation)
  
  	ReleaseSysCache(tuple);
  
! 	if (!reindex_relation(heapOid, true, false))
  		ereport(NOTICE,
  				(errmsg("table \"%s\" has no indexes",
  						relation->relname)));
--- 1629,1635 ----
  
  	ReleaseSysCache(tuple);
  
! 	if (!reindex_relation(heapOid, NULL, true, false))
  		ereport(NOTICE,
  				(errmsg("table \"%s\" has no indexes",
  						relation->relname)));
***************
*** 1742,1748 **** ReindexDatabase(const char *databaseName, bool do_system, bool do_user)
  		StartTransactionCommand();
  		/* functions in indexes may want a snapshot set */
  		PushActiveSnapshot(GetTransactionSnapshot());
! 		if (reindex_relation(relid, true, false))
  			ereport(NOTICE,
  					(errmsg("table \"%s.%s\" was reindexed",
  							get_namespace_name(get_rel_namespace(relid)),
--- 1742,1748 ----
  		StartTransactionCommand();
  		/* functions in indexes may want a snapshot set */
  		PushActiveSnapshot(GetTransactionSnapshot());
! 		if (reindex_relation(relid, NULL, true, false))
  			ereport(NOTICE,
  					(errmsg("table \"%s.%s\" was reindexed",
  							get_namespace_name(get_rel_namespace(relid)),
diff --git a/src/backend/commands/tableindex f3bd565..7c4488e 100644
*** a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c
***************
*** 1076,1082 **** ExecuteTruncate(TruncateStmt *stmt)
  			/*
  			 * Reconstruct the indexes to match, and we're done.
  			 */
! 			reindex_relation(heap_relid, true, false);
  		}
  	}
  
--- 1076,1082 ----
  			/*
  			 * Reconstruct the indexes to match, and we're done.
  			 */
! 			reindex_relation(heap_relid, NULL, true, false);
  		}
  	}
  
***************
*** 2981,2987 **** ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode)
  			(tab->subcmds[AT_PASS_ADD_COL] ||
  			 tab->subcmds[AT_PASS_ALTER_TYPE] ||
  			 tab->subcmds[AT_PASS_COL_ATTRS]))
! 			AlterTableCreateToastTable(tab->relid, (Datum) 0);
  	}
  }
  
--- 2981,2987 ----
  			(tab->subcmds[AT_PASS_ADD_COL] ||
  			 tab->subcmds[AT_PASS_ALTER_TYPE] ||
  			 tab->subcmds[AT_PASS_COL_ATTRS]))
! 			AlterTableCreateToastTable(tab->relid, NULL, (Datum) 0);
  	}
  }
  
***************
*** 3443,3448 **** ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
--- 3443,3457 ----
  		List	   *dropped_attrs = NIL;
  		ListCell   *lc;
  
+ 		if (newrel)
+ 			ereport(DEBUG1,
+ 					(errmsg("rewriting table \"%s\"",
+ 							RelationGetRelationName(oldrel))));
+ 		else
+ 			ereport(DEBUG1,
+ 					(errmsg("verifying table \"%s\"",
+ 							RelationGetRelationName(oldrel))));
+ 
  		econtext = GetPerTupleExprContext(estate);
  
  		/*
***************
*** 3836,3841 **** ATTypedTableRecursion(List **wqueue, Relation rel, AlterTableCmd *cmd,
--- 3845,3854 ----
   * Eventually, we'd like to propagate the check or rewrite operation
   * into other such tables, but for now, just error out if we find any.
   *
+  * CHECK, NOT NULL and DEFAULT constraints and the "oid" system column do
+  * not (currently) follow the row type, so they require no attention here.
+  * The non-propagation of DEFAULT and NOT NULL make ADD COLUMN safe, too.
+  *
   * Caller should provide either a table name or a type name (not both) to
   * report in the error message, if any.
   *
***************
*** 5789,5794 **** validateForeignKeyConstraint(Constraint *fkconstraint,
--- 5802,5811 ----
  	HeapTuple	tuple;
  	Trigger		trig;
  
+ 	ereport(DEBUG1,
+ 			(errmsg("validating foreign key constraint \"%s\"",
+ 					fkconstraint->conname)));
+ 
  	/*
  	 * Build a trigger call structure; we'll need it either way.
  	 */
diff --git a/src/backend/executor/execMindex 600f7e0..56b10a3 100644
*** a/src/backend/executor/execMain.c
--- b/src/backend/executor/execMain.c
***************
*** 2307,2313 **** OpenIntoRel(QueryDesc *queryDesc)
  
  	(void) heap_reloptions(RELKIND_TOASTVALUE, reloptions, true);
  
! 	AlterTableCreateToastTable(intoRelationId, reloptions);
  
  	/*
  	 * And open the constructed table for writing.
--- 2307,2313 ----
  
  	(void) heap_reloptions(RELKIND_TOASTVALUE, reloptions, true);
  
! 	AlterTableCreateToastTable(intoRelationId, NULL, reloptions);
  
  	/*
  	 * And open the constructed table for writing.
diff --git a/src/backend/tcop/utility.index 9500037..e6416e4 100644
*** a/src/backend/tcop/utility.c
--- b/src/backend/tcop/utility.c
***************
*** 540,546 **** standard_ProcessUtility(Node *parsetree,
  						(void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
  											   true);
  
! 						AlterTableCreateToastTable(relOid, toast_options);
  					}
  					else if (IsA(stmt, CreateForeignTableStmt))
  					{
--- 540,546 ----
  						(void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
  											   true);
  
! 						AlterTableCreateToastTable(relOid, NULL, toast_options);
  					}
  					else if (IsA(stmt, CreateForeignTableStmt))
  					{
diff --git a/src/include/catalog/index 2804c63..12656fa 100644
*** a/src/include/catalog/index.h
--- b/src/include/catalog/index.h
***************
*** 70,77 **** extern double IndexBuildHeapScan(Relation heapRelation,
  
  extern void validate_index(Oid heapId, Oid indexId, Snapshot snapshot);
  
! extern void reindex_index(Oid indexId, bool skip_constraint_checks);
! extern bool reindex_relation(Oid relid, bool toast_too, bool heap_rebuilt);
  
  extern bool ReindexIsProcessingHeap(Oid heapOid);
  extern bool ReindexIsProcessingIndex(Oid indexOid);
--- 70,79 ----
  
  extern void validate_index(Oid heapId, Oid indexId, Snapshot snapshot);
  
! extern void reindex_index(Oid indexId, const char *toastFor,
! 			  bool skip_constraint_checks);
! extern bool reindex_relation(Oid relid, const char *toastFor,
! 				 bool toast_too, bool heap_rebuilt);
  
  extern bool ReindexIsProcessingHeap(Oid heapOid);
  extern bool ReindexIsProcessingIndex(Oid indexOid);
diff --git a/src/include/catalog/tindex de3623a..7bd2bdd 100644
*** a/src/include/catalog/toasting.h
--- b/src/include/catalog/toasting.h
***************
*** 17,23 ****
  /*
   * toasting.c prototypes
   */
! extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions);
  extern void BootstrapToastTable(char *relName,
  					Oid toastOid, Oid toastIndexOid);
  
--- 17,24 ----
  /*
   * toasting.c prototypes
   */
! extern void AlterTableCreateToastTable(Oid relOid, const char *finalRelName,
! 						   Datum reloptions);
  extern void BootstrapToastTable(char *relName,
  					Oid toastOid, Oid toastIndexOid);
  
diff --git a/src/include/nodes/execnoindex 546b581..46d9d1a 100644
*** a/src/include/nodes/execnodes.h
--- b/src/include/nodes/execnodes.h
***************
*** 64,69 **** typedef struct IndexInfo
--- 64,70 ----
  	Oid		   *ii_ExclusionOps;	/* array with one entry per column */
  	Oid		   *ii_ExclusionProcs;		/* array with one entry per column */
  	uint16	   *ii_ExclusionStrats;		/* array with one entry per column */
+ 	const char *ii_ToastForRelName;		/* TOAST index only: name of main rel */
  	bool		ii_Unique;
  	bool		ii_ReadyForInserts;
  	bool		ii_Concurrent;
diff --git a/src/test/regress/GNUmakindex 15b9ec4..c33ecb9 100644
diff --git a/src/test/regress/expecindex 3d126bb..282de46 100644
*** a/src/test/regress/expected/alter_table.out
--- b/src/test/regress/expected/alter_table.out
***************
*** 1477,1482 **** create table tab1 (a int, b text);
--- 1477,1648 ----
  create table tab2 (x int, y tab1);
  alter table tab1 alter column b type varchar; -- fails
  ERROR:  cannot alter table "tab1" because column "tab2"."y" uses its rowtype
+ alter table tab1 add check (b <> 'foo');
+ alter table tab1 add c int not null;
+ alter table tab1 add d int not null default 1; -- fails
+ ERROR:  cannot alter table "tab1" because column "tab2"."y" uses its rowtype
+ alter table tab1 drop a;
+ alter table tab1 set with oids;	-- fails
+ ERROR:  cannot alter table "tab1" because column "tab2"."y" uses its rowtype
+ --
+ -- ALTER COLUMN ... SET DATA TYPE optimizations
+ --
+ SET client_min_messages = debug1;	-- Track rewrites.
+ -- Model a type change that throws the semantics of dependent expressions.
+ CREATE DOMAIN trickint AS int;
+ CREATE FUNCTION touchy_f(trickint)	RETURNS int4 LANGUAGE sql AS 'SELECT 100';
+ CREATE FUNCTION touchy_f(int4)		RETURNS int4 LANGUAGE sql AS 'SELECT $1';
+ CREATE DOMAIN lendom AS varchar(8);
+ CREATE DOMAIN checkdom AS text CHECK (VALUE LIKE '<%');
+ CREATE TABLE parent (keycol numeric PRIMARY KEY);
+ DEBUG:  building TOAST index for table "parent"
+ NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "parent_pkey" for table "parent"
+ DEBUG:  building index "parent_pkey" on table "parent"
+ INSERT INTO parent VALUES (0.12), (1.12);
+ CREATE TABLE t (
+ 	integral	int4					NOT NULL,
+ 	rational	numeric(9,4)	UNIQUE	NOT NULL	REFERENCES parent,
+ 	string		varchar(4)				NOT NULL,
+ 	strarr		varchar(2)[]			NOT NULL,
+ 	CHECK (touchy_f(integral) < 10),
+ 	EXCLUDE (integral WITH =)
+ );
+ DEBUG:  building TOAST index for table "t"
+ NOTICE:  CREATE TABLE / UNIQUE will create implicit index "t_rational_key" for table "t"
+ DEBUG:  building index "t_rational_key" on table "t"
+ NOTICE:  CREATE TABLE / EXCLUDE will create implicit index "t_integral_excl" for table "t"
+ DEBUG:  building index "t_integral_excl" on table "t"
+ CREATE INDEX ON t USING gin (strarr);
+ DEBUG:  building index "t_strarr_idx" on table "t"
+ INSERT INTO t VALUES (1, 0.12, '<a/>', '{ab,cd}'), (2, 1.12, '<b/>', '{ef,gh}');
+ -- Comments "rewrite", "verify" and "noop" signify whether ATRewriteTables
+ -- rewrites, scans or does nothing to the table proper.  An "-e" suffix denotes
+ -- an error outcome.
+ ALTER TABLE t ALTER integral TYPE trickint;							-- verify-e
+ DEBUG:  building TOAST index for table "t"
+ DEBUG:  rewriting table "t"
+ ERROR:  check constraint "t_integral_check" is violated by some row
+ ALTER TABLE t DROP CONSTRAINT t_integral_check;
+ ALTER TABLE t ALTER integral TYPE abstime USING integral::abstime;	-- noop
+ DEBUG:  building TOAST index for table "t"
+ DEBUG:  rewriting table "t"
+ DEBUG:  building index "t_rational_key" on table "t"
+ DEBUG:  building index "t_strarr_idx" on table "t"
+ DEBUG:  building index "t_integral_excl" on table "t"
+ ALTER TABLE t ALTER integral TYPE oid USING integral::int4;			-- noop
+ DEBUG:  building TOAST index for table "t"
+ DEBUG:  rewriting table "t"
+ DEBUG:  building index "t_rational_key" on table "t"
+ DEBUG:  building index "t_strarr_idx" on table "t"
+ DEBUG:  building index "t_integral_excl" on table "t"
+ ALTER TABLE t ALTER integral TYPE regtype;							-- noop
+ DEBUG:  building TOAST index for table "t"
+ DEBUG:  rewriting table "t"
+ DEBUG:  building index "t_rational_key" on table "t"
+ DEBUG:  building index "t_strarr_idx" on table "t"
+ DEBUG:  building index "t_integral_excl" on table "t"
+ ALTER TABLE t ALTER rational TYPE numeric(7,4);						-- verify
+ DEBUG:  building TOAST index for table "t"
+ DEBUG:  rewriting table "t"
+ DEBUG:  building index "t_strarr_idx" on table "t"
+ DEBUG:  building index "t_integral_excl" on table "t"
+ DEBUG:  building index "t_rational_key" on table "t"
+ DEBUG:  validating foreign key constraint "t_rational_fkey"
+ ALTER TABLE t ALTER rational TYPE numeric(8,4);						-- noop
+ DEBUG:  building TOAST index for table "t"
+ DEBUG:  rewriting table "t"
+ DEBUG:  building index "t_strarr_idx" on table "t"
+ DEBUG:  building index "t_integral_excl" on table "t"
+ DEBUG:  building index "t_rational_key" on table "t"
+ DEBUG:  validating foreign key constraint "t_rational_fkey"
+ ALTER TABLE t ALTER rational TYPE numeric(8,1);						-- rewrite-e
+ DEBUG:  building TOAST index for table "t"
+ DEBUG:  rewriting table "t"
+ DEBUG:  building index "t_strarr_idx" on table "t"
+ DEBUG:  building index "t_integral_excl" on table "t"
+ DEBUG:  building index "t_rational_key" on table "t"
+ DEBUG:  validating foreign key constraint "t_rational_fkey"
+ ERROR:  insert or update on table "t" violates foreign key constraint "t_rational_fkey"
+ DETAIL:  Key (rational)=(0.1) is not present in table "parent".
+ ALTER TABLE t ALTER string TYPE varchar(6);							-- noop
+ DEBUG:  building TOAST index for table "t"
+ DEBUG:  rewriting table "t"
+ DEBUG:  building index "t_strarr_idx" on table "t"
+ DEBUG:  building index "t_integral_excl" on table "t"
+ DEBUG:  building index "t_rational_key" on table "t"
+ ALTER TABLE t ALTER string TYPE lendom;								-- noop
+ DEBUG:  building TOAST index for table "t"
+ DEBUG:  rewriting table "t"
+ DEBUG:  building index "t_strarr_idx" on table "t"
+ DEBUG:  building index "t_integral_excl" on table "t"
+ DEBUG:  building index "t_rational_key" on table "t"
+ ALTER TABLE t ALTER string TYPE xml USING string::xml;				-- verify
+ DEBUG:  building TOAST index for table "t"
+ DEBUG:  rewriting table "t"
+ DEBUG:  building index "t_strarr_idx" on table "t"
+ DEBUG:  building index "t_integral_excl" on table "t"
+ DEBUG:  building index "t_rational_key" on table "t"
+ ALTER TABLE t ALTER string TYPE checkdom;							-- verify
+ DEBUG:  building TOAST index for table "t"
+ DEBUG:  rewriting table "t"
+ DEBUG:  building index "t_strarr_idx" on table "t"
+ DEBUG:  building index "t_integral_excl" on table "t"
+ DEBUG:  building index "t_rational_key" on table "t"
+ ALTER TABLE t ALTER string TYPE text USING 'foo'::varchar;			-- rewrite
+ DEBUG:  building TOAST index for table "t"
+ DEBUG:  rewriting table "t"
+ DEBUG:  building index "t_strarr_idx" on table "t"
+ DEBUG:  building index "t_integral_excl" on table "t"
+ DEBUG:  building index "t_rational_key" on table "t"
+ ALTER TABLE t ALTER strarr TYPE varchar(4)[];						-- noop
+ DEBUG:  building TOAST index for table "t"
+ DEBUG:  rewriting table "t"
+ DEBUG:  building index "t_integral_excl" on table "t"
+ DEBUG:  building index "t_rational_key" on table "t"
+ DEBUG:  building index "t_strarr_idx" on table "t"
+ ALTER TABLE t ADD CONSTRAINT u0 UNIQUE (integral), -- build index exactly once
+ 			  ALTER integral TYPE int8;								-- rewrite
+ NOTICE:  ALTER TABLE / ADD UNIQUE will create implicit index "u0" for table "t"
+ DEBUG:  building TOAST index for table "t"
+ DEBUG:  rewriting table "t"
+ DEBUG:  building index "t_rational_key" on table "t"
+ DEBUG:  building index "t_strarr_idx" on table "t"
+ DEBUG:  building index "t_integral_excl" on table "t"
+ DEBUG:  building index "u0" on table "t"
+ -- Data and catalog end state.  We omit the columns that bear unstable OIDs.
+ SELECT * FROM t ORDER BY 1;
+  integral | rational | string | strarr  
+ ----------+----------+--------+---------
+         1 |   0.1200 | foo    | {ab,cd}
+         2 |   1.1200 | foo    | {ef,gh}
+ (2 rows)
+ 
+ SELECT relname, indclass FROM pg_index JOIN pg_class c ON c.oid = indexrelid
+ WHERE indrelid = 't'::regclass ORDER BY 1;
+      relname     | indclass 
+ -----------------+----------
+  t_integral_excl | 10029
+  t_rational_key  | 10037
+  t_strarr_idx    | 10103
+  u0              | 10029
+ (4 rows)
+ 
+ SELECT relname, attname, atttypid, atttypmod
+ FROM pg_attribute JOIN pg_class c ON c.oid = attrelid
+ WHERE attnum > 0 AND
+ 	attrelid IN (SELECT indexrelid FROM pg_index WHERE indrelid = 't'::regclass)
+ ORDER BY 1, 2;
+      relname     | attname  | atttypid | atttypmod 
+ -----------------+----------+----------+-----------
+  t_integral_excl | integral |       20 |        -1
+  t_rational_key  | rational |     1700 |    524296
+  t_strarr_idx    | strarr   |     1043 |        -1
+  u0              | integral |       20 |        -1
+ (4 rows)
+ 
+ -- Done.  Retain the table under a less-generic name.
+ ALTER TABLE t RENAME TO alter_type_test;
+ RESET client_min_messages;
  --
  -- lock levels
  --
diff --git a/src/test/regress/expected/big_alternew file mode 100644
index 0000000..1609c01
diff --git a/src/test/regress/sql/alter_table.sql b/index 4895768..8e5090e 100644
*** a/src/test/regress/sql/alter_table.sql
--- b/src/test/regress/sql/alter_table.sql
***************
*** 1094,1099 **** drop table another;
--- 1094,1166 ----
  create table tab1 (a int, b text);
  create table tab2 (x int, y tab1);
  alter table tab1 alter column b type varchar; -- fails
+ alter table tab1 add check (b <> 'foo');
+ alter table tab1 add c int not null;
+ alter table tab1 add d int not null default 1; -- fails
+ alter table tab1 drop a;
+ alter table tab1 set with oids;	-- fails
+ 
+ --
+ -- ALTER COLUMN ... SET DATA TYPE optimizations
+ --
+ SET client_min_messages = debug1;	-- Track rewrites.
+ 
+ -- Model a type change that throws the semantics of dependent expressions.
+ CREATE DOMAIN trickint AS int;
+ CREATE FUNCTION touchy_f(trickint)	RETURNS int4 LANGUAGE sql AS 'SELECT 100';
+ CREATE FUNCTION touchy_f(int4)		RETURNS int4 LANGUAGE sql AS 'SELECT $1';
+ CREATE DOMAIN lendom AS varchar(8);
+ CREATE DOMAIN checkdom AS text CHECK (VALUE LIKE '<%');
+ 
+ CREATE TABLE parent (keycol numeric PRIMARY KEY);
+ INSERT INTO parent VALUES (0.12), (1.12);
+ 
+ CREATE TABLE t (
+ 	integral	int4					NOT NULL,
+ 	rational	numeric(9,4)	UNIQUE	NOT NULL	REFERENCES parent,
+ 	string		varchar(4)				NOT NULL,
+ 	strarr		varchar(2)[]			NOT NULL,
+ 	CHECK (touchy_f(integral) < 10),
+ 	EXCLUDE (integral WITH =)
+ );
+ CREATE INDEX ON t USING gin (strarr);
+ INSERT INTO t VALUES (1, 0.12, '<a/>', '{ab,cd}'), (2, 1.12, '<b/>', '{ef,gh}');
+ 
+ -- Comments "rewrite", "verify" and "noop" signify whether ATRewriteTables
+ -- rewrites, scans or does nothing to the table proper.  An "-e" suffix denotes
+ -- an error outcome.
+ ALTER TABLE t ALTER integral TYPE trickint;							-- verify-e
+ ALTER TABLE t DROP CONSTRAINT t_integral_check;
+ ALTER TABLE t ALTER integral TYPE abstime USING integral::abstime;	-- noop
+ ALTER TABLE t ALTER integral TYPE oid USING integral::int4;			-- noop
+ ALTER TABLE t ALTER integral TYPE regtype;							-- noop
+ ALTER TABLE t ALTER rational TYPE numeric(7,4);						-- verify
+ ALTER TABLE t ALTER rational TYPE numeric(8,4);						-- noop
+ ALTER TABLE t ALTER rational TYPE numeric(8,1);						-- rewrite-e
+ ALTER TABLE t ALTER string TYPE varchar(6);							-- noop
+ ALTER TABLE t ALTER string TYPE lendom;								-- noop
+ ALTER TABLE t ALTER string TYPE xml USING string::xml;				-- verify
+ ALTER TABLE t ALTER string TYPE checkdom;							-- verify
+ ALTER TABLE t ALTER string TYPE text USING 'foo'::varchar;			-- rewrite
+ ALTER TABLE t ALTER strarr TYPE varchar(4)[];						-- noop
+ ALTER TABLE t ADD CONSTRAINT u0 UNIQUE (integral), -- build index exactly once
+ 			  ALTER integral TYPE int8;								-- rewrite
+ 
+ -- Data and catalog end state.  We omit the columns that bear unstable OIDs.
+ SELECT * FROM t ORDER BY 1;
+ 
+ SELECT relname, indclass FROM pg_index JOIN pg_class c ON c.oid = indexrelid
+ WHERE indrelid = 't'::regclass ORDER BY 1;
+ 
+ SELECT relname, attname, atttypid, atttypmod
+ FROM pg_attribute JOIN pg_class c ON c.oid = attrelid
+ WHERE attnum > 0 AND
+ 	attrelid IN (SELECT indexrelid FROM pg_index WHERE indrelid = 't'::regclass)
+ ORDER BY 1, 2;
+ 
+ -- Done.  Retain the table under a less-generic name.
+ ALTER TABLE t RENAME TO alter_type_test;
+ RESET client_min_messages;
  
  --
  -- lock levels
diff --git a/src/test/regress/sql/big_alternew file mode 100644
index 0000000..3824d96