*** a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c
***************
*** 255,261 **** static void createForeignKeyTriggers(Relation rel, Constraint *fkconstraint,
  						 Oid constraintOid, Oid indexOid);
  static void ATController(Relation rel, List *cmds, bool recurse);
  static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
! 		  bool recurse, bool recursing);
  static void ATRewriteCatalogs(List **wqueue);
  static void ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
  		  AlterTableCmd *cmd);
--- 255,261 ----
  						 Oid constraintOid, Oid indexOid);
  static void ATController(Relation rel, List *cmds, bool recurse);
  static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
! 		  bool recurse, int expected_parents);
  static void ATRewriteCatalogs(List **wqueue);
  static void ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
  		  AlterTableCmd *cmd);
***************
*** 266,280 **** static void ATSimplePermissions(Relation rel, bool allowView);
  static void ATSimplePermissionsRelationOrIndex(Relation rel);
  static void ATSimpleRecursion(List **wqueue, Relation rel,
  				  AlterTableCmd *cmd, bool recurse);
- static void ATOneLevelRecursion(List **wqueue, Relation rel,
- 					AlterTableCmd *cmd);
  static void ATPrepAddColumn(List **wqueue, Relation rel, bool recurse,
! 				AlterTableCmd *cmd);
  static void ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
  				ColumnDef *colDef, bool isOid);
  static void add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid);
  static void ATPrepAddOids(List **wqueue, Relation rel, bool recurse,
! 			  AlterTableCmd *cmd);
  static void ATExecDropNotNull(Relation rel, const char *colName);
  static void ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
  				 const char *colName);
--- 266,278 ----
  static void ATSimplePermissionsRelationOrIndex(Relation rel);
  static void ATSimpleRecursion(List **wqueue, Relation rel,
  				  AlterTableCmd *cmd, bool recurse);
  static void ATPrepAddColumn(List **wqueue, Relation rel, bool recurse,
! 				int expected_parents, AlterTableCmd *cmd);
  static void ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
  				ColumnDef *colDef, bool isOid);
  static void add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid);
  static void ATPrepAddOids(List **wqueue, Relation rel, bool recurse,
! 				int expected_parents, AlterTableCmd *cmd);
  static void ATExecDropNotNull(Relation rel, const char *colName);
  static void ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
  				 const char *colName);
***************
*** 309,315 **** static void ATExecDropConstraint(Relation rel, const char *constrName,
  								 bool missing_ok);
  static void ATPrepAlterColumnType(List **wqueue,
  					  AlteredTableInfo *tab, Relation rel,
! 					  bool recurse, bool recursing,
  					  AlterTableCmd *cmd);
  static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
  					  const char *colName, TypeName *typeName);
--- 307,313 ----
  								 bool missing_ok);
  static void ATPrepAlterColumnType(List **wqueue,
  					  AlteredTableInfo *tab, Relation rel,
! 					  bool recurse, int expected_parents,
  					  AlterTableCmd *cmd);
  static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
  					  const char *colName, TypeName *typeName);
***************
*** 2388,2394 **** ATController(Relation rel, List *cmds, bool recurse)
  	{
  		AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
  
! 		ATPrepCmd(&wqueue, rel, cmd, recurse, false);
  	}
  
  	/* Close the relation, but keep lock until commit */
--- 2386,2392 ----
  	{
  		AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
  
! 		ATPrepCmd(&wqueue, rel, cmd, recurse, 0);
  	}
  
  	/* Close the relation, but keep lock until commit */
***************
*** 2412,2418 **** ATController(Relation rel, List *cmds, bool recurse)
   */
  static void
  ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
! 		  bool recurse, bool recursing)
  {
  	AlteredTableInfo *tab;
  	int			pass;
--- 2410,2416 ----
   */
  static void
  ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
! 		  bool recurse, int expected_parents)
  {
  	AlteredTableInfo *tab;
  	int			pass;
***************
*** 2437,2450 **** ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
  		case AT_AddColumn:		/* ADD COLUMN */
  			ATSimplePermissions(rel, false);
  			/* Performs own recursion */
! 			ATPrepAddColumn(wqueue, rel, recurse, cmd);
  			pass = AT_PASS_ADD_COL;
  			break;
  		case AT_AddColumnToView:		/* add column via CREATE OR REPLACE
  										 * VIEW */
  			ATSimplePermissions(rel, true);
  			/* Performs own recursion */
! 			ATPrepAddColumn(wqueue, rel, recurse, cmd);
  			pass = AT_PASS_ADD_COL;
  			break;
  		case AT_ColumnDefault:	/* ALTER COLUMN DEFAULT */
--- 2435,2448 ----
  		case AT_AddColumn:		/* ADD COLUMN */
  			ATSimplePermissions(rel, false);
  			/* Performs own recursion */
! 			ATPrepAddColumn(wqueue, rel, recurse, expected_parents, cmd);
  			pass = AT_PASS_ADD_COL;
  			break;
  		case AT_AddColumnToView:		/* add column via CREATE OR REPLACE
  										 * VIEW */
  			ATSimplePermissions(rel, true);
  			/* Performs own recursion */
! 			ATPrepAddColumn(wqueue, rel, recurse, expected_parents, cmd);
  			pass = AT_PASS_ADD_COL;
  			break;
  		case AT_ColumnDefault:	/* ALTER COLUMN DEFAULT */
***************
*** 2523,2529 **** ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
  		case AT_AlterColumnType:		/* ALTER COLUMN TYPE */
  			ATSimplePermissions(rel, false);
  			/* Performs own recursion */
! 			ATPrepAlterColumnType(wqueue, tab, rel, recurse, recursing, cmd);
  			pass = AT_PASS_ALTER_TYPE;
  			break;
  		case AT_ChangeOwner:	/* ALTER OWNER */
--- 2521,2528 ----
  		case AT_AlterColumnType:		/* ALTER COLUMN TYPE */
  			ATSimplePermissions(rel, false);
  			/* Performs own recursion */
! 			ATPrepAlterColumnType(wqueue, tab, rel,
! 								  recurse, expected_parents, cmd);
  			pass = AT_PASS_ALTER_TYPE;
  			break;
  		case AT_ChangeOwner:	/* ALTER OWNER */
***************
*** 2541,2548 **** ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
  		case AT_AddOids:		/* SET WITH OIDS */
  			ATSimplePermissions(rel, false);
  			/* Performs own recursion */
! 			if (!rel->rd_rel->relhasoids || recursing)
! 				ATPrepAddOids(wqueue, rel, recurse, cmd);
  			pass = AT_PASS_ADD_COL;
  			break;
  		case AT_DropOids:		/* SET WITHOUT OIDS */
--- 2540,2547 ----
  		case AT_AddOids:		/* SET WITH OIDS */
  			ATSimplePermissions(rel, false);
  			/* Performs own recursion */
! 			if (!rel->rd_rel->relhasoids || expected_parents > 0)
! 				ATPrepAddOids(wqueue, rel, recurse, expected_parents, cmd);
  			pass = AT_PASS_ADD_COL;
  			break;
  		case AT_DropOids:		/* SET WITHOUT OIDS */
***************
*** 2555,2561 **** ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
  				dropCmd->subtype = AT_DropColumn;
  				dropCmd->name = pstrdup("oid");
  				dropCmd->behavior = cmd->behavior;
! 				ATPrepCmd(wqueue, rel, dropCmd, recurse, false);
  			}
  			pass = AT_PASS_DROP;
  			break;
--- 2554,2560 ----
  				dropCmd->subtype = AT_DropColumn;
  				dropCmd->name = pstrdup("oid");
  				dropCmd->behavior = cmd->behavior;
! 				ATPrepCmd(wqueue, rel, dropCmd, recurse, expected_parents);
  			}
  			pass = AT_PASS_DROP;
  			break;
***************
*** 3421,3439 **** ATSimpleRecursion(List **wqueue, Relation rel,
  	if (recurse && rel->rd_rel->relkind == RELKIND_RELATION)
  	{
  		Oid			relid = RelationGetRelid(rel);
! 		ListCell   *child;
  		List	   *children;
  
! 		children = find_all_inheritors(relid, AccessExclusiveLock, NULL);
  
  		/*
  		 * find_all_inheritors does the recursive search of the inheritance
  		 * hierarchy, so all we have to do is process all of the relids in the
  		 * list that it returns.
  		 */
! 		foreach(child, children)
  		{
! 			Oid			childrelid = lfirst_oid(child);
  			Relation	childrel;
  
  			if (childrelid == relid)
--- 3420,3440 ----
  	if (recurse && rel->rd_rel->relkind == RELKIND_RELATION)
  	{
  		Oid			relid = RelationGetRelid(rel);
! 		ListCell   *lc, *lp;
  		List	   *children;
+ 		List	   *numparents;
  
! 		children = find_all_inheritors(relid, AccessExclusiveLock, &numparents);
  
  		/*
  		 * find_all_inheritors does the recursive search of the inheritance
  		 * hierarchy, so all we have to do is process all of the relids in the
  		 * list that it returns.
  		 */
! 		forboth(lc, children, lp, numparents)
  		{
! 			Oid			childrelid = lfirst_oid(lc);
! 			int			expected_parents = lfirst_int(lp);
  			Relation	childrel;
  
  			if (childrelid == relid)
***************
*** 3441,3485 **** ATSimpleRecursion(List **wqueue, Relation rel,
  			/* find_all_inheritors already got lock */
  			childrel = relation_open(childrelid, NoLock);
  			CheckTableNotInUse(childrel, "ALTER TABLE");
! 			ATPrepCmd(wqueue, childrel, cmd, false, true);
  			relation_close(childrel, NoLock);
  		}
  	}
  }
  
  /*
-  * ATOneLevelRecursion
-  *
-  * Here, we visit only direct inheritance children.  It is expected that
-  * the command's prep routine will recurse again to find indirect children.
-  * When using this technique, a multiply-inheriting child will be visited
-  * multiple times.
-  */
- static void
- ATOneLevelRecursion(List **wqueue, Relation rel,
- 					AlterTableCmd *cmd)
- {
- 	Oid			relid = RelationGetRelid(rel);
- 	ListCell   *child;
- 	List	   *children;
- 
- 	children = find_inheritance_children(relid, AccessExclusiveLock);
- 
- 	foreach(child, children)
- 	{
- 		Oid			childrelid = lfirst_oid(child);
- 		Relation	childrel;
- 
- 		/* find_inheritance_children already got lock */
- 		childrel = relation_open(childrelid, NoLock);
- 		CheckTableNotInUse(childrel, "ALTER TABLE");
- 		ATPrepCmd(wqueue, childrel, cmd, true, true);
- 		relation_close(childrel, NoLock);
- 	}
- }
- 
- 
- /*
   * find_composite_type_dependencies
   *
   * Check to see if a composite type is being used as a column in some
--- 3442,3454 ----
  			/* find_all_inheritors already got lock */
  			childrel = relation_open(childrelid, NoLock);
  			CheckTableNotInUse(childrel, "ALTER TABLE");
! 			ATPrepCmd(wqueue, childrel, cmd, false, expected_parents);
  			relation_close(childrel, NoLock);
  		}
  	}
  }
  
  /*
   * find_composite_type_dependencies
   *
   * Check to see if a composite type is being used as a column in some
***************
*** 3591,3627 **** find_composite_type_dependencies(Oid typeOid,
   */
  static void
  ATPrepAddColumn(List **wqueue, Relation rel, bool recurse,
! 				AlterTableCmd *cmd)
  {
  	/*
  	 * Recurse to add the column to child classes, if requested.
  	 *
! 	 * We must recurse one level at a time, so that multiply-inheriting
! 	 * children are visited the right number of times and end up with the
! 	 * right attinhcount.
  	 */
  	if (recurse)
! 	{
! 		AlterTableCmd *childCmd = copyObject(cmd);
! 		ColumnDef  *colDefChild = (ColumnDef *) childCmd->def;
! 
! 		/* Child should see column as singly inherited */
! 		colDefChild->inhcount = 1;
! 		colDefChild->is_local = false;
! 
! 		ATOneLevelRecursion(wqueue, rel, childCmd);
! 	}
! 	else
! 	{
! 		/*
! 		 * If we are told not to recurse, there had better not be any child
! 		 * tables; else the addition would put them out of step.
! 		 */
! 		if (find_inheritance_children(RelationGetRelid(rel), NoLock) != NIL)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
! 					 errmsg("column must be added to child tables too")));
! 	}
  }
  
  static void
--- 3560,3587 ----
   */
  static void
  ATPrepAddColumn(List **wqueue, Relation rel, bool recurse,
! 				int expected_parents, AlterTableCmd *cmd)
  {
+ 	ColumnDef  *colDef = (ColumnDef *)cmd->def;
+ 
+ 	colDef->inhcount = expected_parents;
+ 
+ 	colDef->is_local = (expected_parents == 0 ? true : false);
+ 
  	/*
  	 * Recurse to add the column to child classes, if requested.
  	 *
! 	 * ATExecAddColumn creates a new column with attinhcount which shall be
! 	 * initialized by colDef->inhcount, or increments attinhcount of the
! 	 * existing column to be merged by colDef->inhcount.
  	 */
  	if (recurse)
! 		ATSimpleRecursion(wqueue, rel, cmd, recurse);
! 	else if (expected_parents == 0 &&
! 			 find_inheritance_children(RelationGetRelid(rel), NoLock) != NIL)
! 		ereport(ERROR,
! 				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
! 				 errmsg("column must be added to child tables too")));
  }
  
  static void
***************
*** 3681,3687 **** ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
  						RelationGetRelationName(rel), colDef->colname)));
  
  			/* Bump the existing child att's inhcount */
! 			childatt->attinhcount++;
  			simple_heap_update(attrdesc, &tuple->t_self, tuple);
  			CatalogUpdateIndexes(attrdesc, tuple);
  
--- 3641,3647 ----
  						RelationGetRelationName(rel), colDef->colname)));
  
  			/* Bump the existing child att's inhcount */
! 			childatt->attinhcount += colDef->inhcount;
  			simple_heap_update(attrdesc, &tuple->t_self, tuple);
  			CatalogUpdateIndexes(attrdesc, tuple);
  
***************
*** 3915,3921 **** add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid)
   * to cons up a ColumnDef node because the ADD COLUMN code needs one.
   */
  static void
! ATPrepAddOids(List **wqueue, Relation rel, bool recurse, AlterTableCmd *cmd)
  {
  	/* If we're recursing to a child table, the ColumnDef is already set up */
  	if (cmd->def == NULL)
--- 3875,3882 ----
   * to cons up a ColumnDef node because the ADD COLUMN code needs one.
   */
  static void
! ATPrepAddOids(List **wqueue, Relation rel, bool recurse,
! 			  int expected_parents, AlterTableCmd *cmd)
  {
  	/* If we're recursing to a child table, the ColumnDef is already set up */
  	if (cmd->def == NULL)
***************
*** 3930,3936 **** ATPrepAddOids(List **wqueue, Relation rel, bool recurse, AlterTableCmd *cmd)
  		cdef->storage = 0;
  		cmd->def = (Node *) cdef;
  	}
! 	ATPrepAddColumn(wqueue, rel, recurse, cmd);
  }
  
  /*
--- 3891,3897 ----
  		cdef->storage = 0;
  		cmd->def = (Node *) cdef;
  	}
! 	ATPrepAddColumn(wqueue, rel, recurse, expected_parents, cmd);
  }
  
  /*
***************
*** 5805,5811 **** ATExecDropConstraint(Relation rel, const char *constrName,
  static void
  ATPrepAlterColumnType(List **wqueue,
  					  AlteredTableInfo *tab, Relation rel,
! 					  bool recurse, bool recursing,
  					  AlterTableCmd *cmd)
  {
  	char	   *colName = cmd->name;
--- 5766,5772 ----
  static void
  ATPrepAlterColumnType(List **wqueue,
  					  AlteredTableInfo *tab, Relation rel,
! 					  bool recurse, int expected_parents,
  					  AlterTableCmd *cmd)
  {
  	char	   *colName = cmd->name;
***************
*** 5837,5843 **** ATPrepAlterColumnType(List **wqueue,
  						colName)));
  
  	/* Don't alter inherited columns */
! 	if (attTup->attinhcount > 0 && !recursing)
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
  				 errmsg("cannot alter inherited column \"%s\"",
--- 5798,5804 ----
  						colName)));
  
  	/* Don't alter inherited columns */
! 	if (attTup->attinhcount > expected_parents)
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
  				 errmsg("cannot alter inherited column \"%s\"",
***************
*** 5929,5935 **** ATPrepAlterColumnType(List **wqueue,
  	 */
  	if (recurse)
  		ATSimpleRecursion(wqueue, rel, cmd, recurse);
! 	else if (!recursing &&
  			 find_inheritance_children(RelationGetRelid(rel), NoLock) != NIL)
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
--- 5890,5896 ----
  	 */
  	if (recurse)
  		ATSimpleRecursion(wqueue, rel, cmd, recurse);
! 	else if (expected_parents == 0 &&
  			 find_inheritance_children(RelationGetRelid(rel), NoLock) != NIL)
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
