88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.320 2010/01/28 23:21:11 petere Exp $
11+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.321 2010/02/01 19:28:56 rhaas Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -824,7 +824,7 @@ ExecuteTruncate(TruncateStmt *stmt)
824824ListCell * child ;
825825List * children ;
826826
827- children = find_all_inheritors (myrelid ,AccessExclusiveLock );
827+ children = find_all_inheritors (myrelid ,AccessExclusiveLock , NULL );
828828
829829foreach (child ,children )
830830{
@@ -1943,7 +1943,7 @@ renameatt(Oid myrelid,
19431943const char * oldattname ,
19441944const char * newattname ,
19451945bool recurse ,
1946- bool recursing )
1946+ int expected_parents )
19471947{
19481948Relation targetrelation ;
19491949Relation attrelation ;
@@ -1987,33 +1987,42 @@ renameatt(Oid myrelid,
19871987 */
19881988if (recurse )
19891989{
1990- ListCell * child ;
1991- List * children ;
1990+ List * child_oids , * child_numparents ;
1991+ ListCell * lo , * li ;
19921992
1993- children = find_all_inheritors (myrelid ,AccessExclusiveLock );
1993+ /*
1994+ * we need the number of parents for each child so that the recursive
1995+ * calls to renameatt() can determine whether there are any parents
1996+ * outside the inheritance hierarchy being processed.
1997+ */
1998+ child_oids = find_all_inheritors (myrelid ,AccessExclusiveLock ,
1999+ & child_numparents );
19942000
19952001/*
19962002 * find_all_inheritors does the recursive search of the inheritance
19972003 * hierarchy, so all we have to do is process all of the relids in the
19982004 * list that it returns.
19992005 */
2000- foreach ( child , children )
2006+ forboth ( lo , child_oids , li , child_numparents )
20012007{
2002- Oid childrelid = lfirst_oid (child );
2008+ Oid childrelid = lfirst_oid (lo );
2009+ int numparents = lfirst_int (li );
20032010
20042011if (childrelid == myrelid )
20052012continue ;
20062013/* note we need not recurse again */
2007- renameatt (childrelid ,oldattname ,newattname , false,true );
2014+ renameatt (childrelid ,oldattname ,newattname , false,numparents );
20082015}
20092016}
20102017else
20112018{
20122019/*
20132020 * If we are told not to recurse, there had better not be any child
20142021 * tables; else the rename would put them out of step.
2022+ *
2023+ * expected_parents will only be 0 if we are not already recursing.
20152024 */
2016- if (! recursing &&
2025+ if (expected_parents == 0 &&
20172026find_inheritance_children (myrelid ,NoLock )!= NIL )
20182027ereport (ERROR ,
20192028(errcode (ERRCODE_INVALID_TABLE_DEFINITION ),
@@ -2039,10 +2048,15 @@ renameatt(Oid myrelid,
20392048oldattname )));
20402049
20412050/*
2042- * if the attribute is inherited, forbid the renaming, unless we are
2043- * already inside a recursive rename.
2051+ * if the attribute is inherited, forbid the renaming. if this is a
2052+ * top-level call to renameatt(), then expected_parents will be 0, so the
2053+ * effect of this code will be to prohibit the renaming if the attribute
2054+ * is inherited at all. if this is a recursive call to renameatt(),
2055+ * expected_parents will be the number of parents the current relation has
2056+ * within the inheritance hierarchy being processed, so we'll prohibit
2057+ * the renaming only if there are additional parents from elsewhere.
20442058 */
2045- if (attform -> attinhcount > 0 && ! recursing )
2059+ if (attform -> attinhcount > expected_parents )
20462060ereport (ERROR ,
20472061(errcode (ERRCODE_INVALID_TABLE_DEFINITION ),
20482062errmsg ("cannot rename inherited column \"%s\"" ,
@@ -3410,7 +3424,7 @@ ATSimpleRecursion(List **wqueue, Relation rel,
34103424ListCell * child ;
34113425List * children ;
34123426
3413- children = find_all_inheritors (relid ,AccessExclusiveLock );
3427+ children = find_all_inheritors (relid ,AccessExclusiveLock , NULL );
34143428
34153429/*
34163430 * find_all_inheritors does the recursive search of the inheritance
@@ -7233,7 +7247,7 @@ ATExecAddInherit(Relation child_rel, RangeVar *parent)
72337247 * We use weakest lock we can on child's children, namely AccessShareLock.
72347248 */
72357249children = find_all_inheritors (RelationGetRelid (child_rel ),
7236- AccessShareLock );
7250+ AccessShareLock , NULL );
72377251
72387252if (list_member_oid (children ,RelationGetRelid (parent_rel )))
72397253ereport (ERROR ,