From c2793d9200948d693150a5bbeb3815e3b5404be2 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp>
Date: Tue, 12 Dec 2017 17:38:12 +0900
Subject: [PATCH 2/2] Lock parent on ALTER TABLE NO INHERIT

NO INHERIT doesn't modify the parent at all but lock is required to
avoid error caused when a concurrent access see a false child.
---
 src/backend/commands/tablecmds.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d979ce2..a8d119f 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -13246,7 +13246,28 @@ RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, Oid oldrelid,
 		reltype = ((AlterObjectSchemaStmt *) stmt)->objectType;
 
 	else if (IsA(stmt, AlterTableStmt))
-		reltype = ((AlterTableStmt *) stmt)->relkind;
+	{
+		AlterTableStmt *alterstmt = (AlterTableStmt *)stmt;
+		ListCell *lc;
+
+		reltype = alterstmt->relkind;
+
+		foreach (lc, alterstmt->cmds)
+		{
+			AlterTableCmd *cmd = lfirst_node(AlterTableCmd, lc);
+			Assert(IsA(cmd, AlterTableCmd));
+
+			/*
+			 * Though NO INHERIT doesn't modify the parent, lock on the parent
+			 * is necessary so that no concurrent expansion of inheritances
+			 * sees a false child and ends with ERROR.  But no need to ascend
+			 * further.
+			 */
+			if (cmd->subtype == AT_DropInherit)
+				RangeVarGetRelid((RangeVar *)cmd->def,
+								 AccessExclusiveLock, false);
+		}
+	}
 	else
 	{
 		reltype = OBJECT_TABLE; /* placate compiler */
-- 
2.9.2

