diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml
index f9576da..59f939c 100644
--- a/doc/src/sgml/ref/alter_table.sgml
+++ b/doc/src/sgml/ref/alter_table.sgml
@@ -59,6 +59,7 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
     ADD <replaceable class="parameter">table_constraint</replaceable> [ NOT VALID ]
     ADD <replaceable class="parameter">table_constraint_using_index</replaceable>
     ALTER CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+    ALTER CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> SET [INHERIT | NO INHERIT]
     VALIDATE CONSTRAINT <replaceable class="parameter">constraint_name</replaceable>
     DROP CONSTRAINT [ IF EXISTS ]  <replaceable class="parameter">constraint_name</replaceable> [ RESTRICT | CASCADE ]
     DISABLE TRIGGER [ <replaceable class="parameter">trigger_name</replaceable> | ALL | USER ]
@@ -551,11 +552,31 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
     <listitem>
      <para>
       This form alters the attributes of a constraint that was previously
-      created. Currently only foreign key constraints may be altered.
+      created. Currently only foreign key constraints may be altered in
+      this fashion, but see below.
      </para>
     </listitem>
    </varlistentry>
 
+   <varlistentry id="sql-altertable-desc-alter-constraint-inherit">
+    <term><literal>ALTER CONSTRAINT ... SET INHERIT</literal></term>
+    <term><literal>ALTER CONSTRAINT ... SET NO INHERIT</literal></term>
+    <listitem>
+     <para>
+      This form modifies a inheritable constraint so that it becomes not
+      inheritable, or vice-versa. Only not-null constraints may be altered
+      in this fashion at present.
+      In addition to changing the inheritability status of the constraint,
+      in the case where a non-inheritable constraint is being marked
+      inheritable, if the table has children, an equivalent constraint
+      is added to them. If marking an inheritable constraint as
+      non-inheritable on a table with children, then the corresponding
+      constraint on children will be marked as no longer inherited,
+      but not removed.
+      </para>
+     </listitem>
+    </varlistentry>
+
    <varlistentry id="sql-altertable-desc-validate-constraint">
     <term><literal>VALIDATE CONSTRAINT</literal></term>
     <listitem>
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 18f64db..fa6231a 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -391,6 +391,10 @@ static void AlterSeqNamespaces(Relation classRel, Relation rel,
 							   LOCKMODE lockmode);
 static ObjectAddress ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd,
 										   bool recurse, bool recursing, LOCKMODE lockmode);
+static ObjectAddress ATExecAlterConstraintInherit(List **wqueue, Relation rel, AlterTableCmd *cmd,
+										   bool recurse, bool recursing, LOCKMODE lockmode);
+static ObjectAddress ATExecAlterConstraintNoInherit(Relation rel, AlterTableCmd *cmd,
+													LOCKMODE lockmode);
 static bool ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel,
 									 Relation rel, HeapTuple contuple, List **otherrelids,
 									 LOCKMODE lockmode);
@@ -476,6 +480,8 @@ static ObjectAddress ATExecSetNotNull(List **wqueue, Relation rel,
 									  char *constrname, char *colName,
 									  bool recurse, bool recursing,
 									  LOCKMODE lockmode);
+static ObjectAddress ATExecSetNotNullNoInherit(Relation rel, char *conName,
+											   char *colName, LOCKMODE lockmode);
 static bool NotNullImpliedByRelConstraints(Relation rel, Form_pg_attribute attr);
 static bool ConstraintImpliedByRelConstraint(Relation scanrel,
 											 List *testConstraint, List *provenConstraint);
@@ -4660,6 +4666,8 @@ AlterTableGetLockLevel(List *cmds)
 			case AT_SetExpression:
 			case AT_DropExpression:
 			case AT_SetCompression:
+			case AT_AlterConstraintInherit:
+			case AT_AlterConstraintNoInherit:
 				cmd_lockmode = AccessExclusiveLock;
 				break;
 
@@ -5154,6 +5162,18 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
 			/* Recursion occurs during execution phase */
 			pass = AT_PASS_MISC;
 			break;
+		case AT_AlterConstraintInherit:	/* ALTER CONSTRAINT SET INHERIT*/
+			ATSimplePermissions(cmd->subtype, rel,
+								ATT_TABLE | ATT_PARTITIONED_TABLE);
+			/* Recursion occurs during execution phase */
+			pass = AT_PASS_MISC;
+			break;
+		case AT_AlterConstraintNoInherit:	/* ALTER CONSTRAINT SET NO INHERIT */
+			ATSimplePermissions(cmd->subtype, rel,
+								ATT_TABLE | ATT_PARTITIONED_TABLE);
+			/* Recursion occurs during execution phase */
+			pass = AT_PASS_MISC;
+			break;
 		case AT_ValidateConstraint: /* VALIDATE CONSTRAINT */
 			ATSimplePermissions(cmd->subtype, rel,
 								ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
@@ -5434,6 +5454,13 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab,
 		case AT_AlterConstraint:	/* ALTER CONSTRAINT */
 			address = ATExecAlterConstraint(rel, cmd, false, false, lockmode);
 			break;
+		case AT_AlterConstraintInherit:	/* ALTER CONSTRAINT SET INHERIT */
+			address = ATExecAlterConstraintInherit(wqueue, rel, cmd,
+												   true, true, lockmode);
+			break;
+		case AT_AlterConstraintNoInherit:	/* ALTER CONSTRAINT SET NO INHERIT */
+			address = ATExecAlterConstraintNoInherit(rel, cmd, lockmode);
+			break;
 		case AT_ValidateConstraint: /* VALIDATE CONSTRAINT */
 			address = ATExecValidateConstraint(wqueue, rel, cmd->name, cmd->recurse,
 											   false, lockmode);
@@ -6518,6 +6545,10 @@ alter_table_type_to_string(AlterTableType cmdtype)
 			return "ADD CONSTRAINT";
 		case AT_AlterConstraint:
 			return "ALTER CONSTRAINT";
+		case AT_AlterConstraintInherit:
+			return "ALTER CONSTRAINT ... SET INHERIT";
+		case AT_AlterConstraintNoInherit:
+			return "ALTER CONSTRAINT ... SET NO INHERIT";
 		case AT_ValidateConstraint:
 			return "VALIDATE CONSTRAINT";
 		case AT_DropConstraint:
@@ -21034,3 +21065,331 @@ GetAttributeStorage(Oid atttypid, const char *storagemode)
 
 	return cstorage;
 }
+
+/*
+ * ALTER TABLE ALTER CONSTRAINT SET INHERIT
+ *
+ * Make the constraint as inherit and recurse the constraint to childrens if
+ * any.
+ *
+ * Currently only works for not null constraints.
+ *
+ * If the constraint is modified, returns its address; otherwise, return
+ * InvalidObjectAddress.
+ */
+static ObjectAddress
+ATExecAlterConstraintInherit(List **wqueue, Relation rel,
+							 AlterTableCmd *cmd, bool recurse,
+							 bool recursing, LOCKMODE lockmode)
+{
+	Relation	conrel;
+	Relation	tgrel;
+	SysScanDesc scan;
+	ScanKeyData skey[3];
+	HeapTuple	contuple;
+	Form_pg_constraint currcon;
+	ObjectAddress address = InvalidObjectAddress;
+	AttrNumber	colNum;
+	char	   *colName;
+	List	   *children;
+
+	conrel = table_open(ConstraintRelationId, RowExclusiveLock);
+	tgrel = table_open(TriggerRelationId, RowExclusiveLock);
+
+	/*
+	 * Find and check the target constraint
+	 */
+	ScanKeyInit(&skey[0],
+				Anum_pg_constraint_conrelid,
+				BTEqualStrategyNumber, F_OIDEQ,
+				ObjectIdGetDatum(RelationGetRelid(rel)));
+	ScanKeyInit(&skey[1],
+				Anum_pg_constraint_contypid,
+				BTEqualStrategyNumber, F_OIDEQ,
+				ObjectIdGetDatum(InvalidOid));
+	ScanKeyInit(&skey[2],
+				Anum_pg_constraint_conname,
+				BTEqualStrategyNumber, F_NAMEEQ,
+				CStringGetDatum(cmd->name));
+	scan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId,
+							  true, NULL, 3, skey);
+
+	/* There can be at most one matching row */
+	if (!HeapTupleIsValid(contuple = systable_getnext(scan)))
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("constraint \"%s\" of relation \"%s\" does not exist",
+						cmd->name, RelationGetRelationName(rel))));
+
+	contuple = heap_copytuple(contuple);
+
+	currcon = (Form_pg_constraint) GETSTRUCT(contuple);
+
+	if (currcon->contype != CONSTRAINT_NOTNULL)
+		ereport(ERROR,
+			(errcode(ERRCODE_WRONG_OBJECT_TYPE),
+			 errmsg("ALTER TABLE \"%s\" ALTER CONSTRAINT \"%s\" SET INHERIT only supports not null constraint",
+					RelationGetRelationName(rel), cmd->name)));
+
+	/* Return if constraint is already marked as INHERIT. */
+	if (!currcon->connoinherit)
+	{
+		systable_endscan(scan);
+
+		table_close(tgrel, RowExclusiveLock);
+		table_close(conrel, RowExclusiveLock);
+		heap_freetuple(contuple);
+
+		return address;
+	}
+
+	/* Update the constraint tuple and mark connoinherit as false. */
+	currcon->connoinherit = false;
+
+	CatalogTupleUpdate(conrel, &contuple->t_self, contuple);
+	ObjectAddressSet(address, ConstraintRelationId, currcon->oid);
+	CommandCounterIncrement();
+
+	systable_endscan(scan);
+
+	table_close(tgrel, RowExclusiveLock);
+	table_close(conrel, RowExclusiveLock);
+
+	/* fetch the column number and name */
+	colNum = extractNotNullColumn(contuple);
+	colName = get_attname(currcon->conrelid, colNum, false);
+
+	/*
+	 * Recurse to propagate the constraint to children that don't have one.
+	 */
+	children = find_inheritance_children(RelationGetRelid(rel),
+										 lockmode);
+
+	foreach_oid(childoid, children)
+	{
+		Relation	childrel = table_open(childoid, NoLock);
+		ObjectAddress addr;
+
+		addr = ATExecSetNotNull(wqueue, childrel, NameStr(currcon->conname),
+								colName, recurse, recursing, lockmode);
+		if (OidIsValid(addr.objectId))
+			CommandCounterIncrement();
+
+		table_close(childrel, NoLock);
+	}
+
+	heap_freetuple(contuple);
+
+	return address;
+}
+
+
+/*
+ * ALTER TABLE ALTER CONSTRAINT SET NO INHERIT
+ *
+ * Make the constraint as inherit and recurse to the childrens and decrement
+ * their inheritance count.
+ *
+ * Currently only works for not null constraints.
+ *
+ * If the constraint is modified, returns its address; otherwise, return
+ * InvalidObjectAddress.
+ */
+static ObjectAddress
+ATExecAlterConstraintNoInherit(Relation rel, AlterTableCmd *cmd,
+							   LOCKMODE lockmode)
+{
+	Relation	conrel;
+	Relation	tgrel;
+	SysScanDesc scan;
+	ScanKeyData skey[3];
+	HeapTuple	contuple;
+	Form_pg_constraint currcon;
+	ObjectAddress address = InvalidObjectAddress;
+	AttrNumber	colNum;
+	char	   *colName;
+	List	   *children;
+
+	conrel = table_open(ConstraintRelationId, RowExclusiveLock);
+	tgrel = table_open(TriggerRelationId, RowExclusiveLock);
+
+	/*
+	 * Find and check the target constraint
+	 */
+	ScanKeyInit(&skey[0],
+				Anum_pg_constraint_conrelid,
+				BTEqualStrategyNumber, F_OIDEQ,
+				ObjectIdGetDatum(RelationGetRelid(rel)));
+	ScanKeyInit(&skey[1],
+				Anum_pg_constraint_contypid,
+				BTEqualStrategyNumber, F_OIDEQ,
+				ObjectIdGetDatum(InvalidOid));
+	ScanKeyInit(&skey[2],
+				Anum_pg_constraint_conname,
+				BTEqualStrategyNumber, F_NAMEEQ,
+				CStringGetDatum(cmd->name));
+	scan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId,
+							  true, NULL, 3, skey);
+
+	/* There can be at most one matching row */
+	if (!HeapTupleIsValid(contuple = systable_getnext(scan)))
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("constraint \"%s\" of relation \"%s\" does not exist",
+						cmd->name, RelationGetRelationName(rel))));
+
+	contuple = heap_copytuple(contuple);
+
+	currcon = (Form_pg_constraint) GETSTRUCT(contuple);
+
+	if (currcon->contype != CONSTRAINT_NOTNULL)
+		ereport(ERROR,
+			(errcode(ERRCODE_WRONG_OBJECT_TYPE),
+			 errmsg("ALTER TABLE \"%s\" ALTER CONSTRAINT \"%s\" SET NO INHERIT only supports not null constraint",
+					RelationGetRelationName(rel), cmd->name)));
+
+	/* Return if constraint is already marked as NO INHERIT. */
+	if (currcon->connoinherit)
+	{
+		systable_endscan(scan);
+
+		table_close(tgrel, RowExclusiveLock);
+		table_close(conrel, RowExclusiveLock);
+		heap_freetuple(contuple);
+
+		return address;
+	}
+
+	/* Update the constraint tuple and mark connoinherit as true. */
+	currcon->connoinherit = true;
+
+	CatalogTupleUpdate(conrel, &contuple->t_self, contuple);
+	ObjectAddressSet(address, ConstraintRelationId, currcon->oid);
+	CommandCounterIncrement();
+
+	systable_endscan(scan);
+
+	table_close(tgrel, RowExclusiveLock);
+	table_close(conrel, RowExclusiveLock);
+
+	/* fetch the column number and name */
+	colNum = extractNotNullColumn(contuple);
+	colName = get_attname(currcon->conrelid, colNum, false);
+
+	/*
+	 * Recurse to propagate the constraint to children that don't have one.
+	 */
+	children = find_inheritance_children(RelationGetRelid(rel),
+										 lockmode);
+
+	foreach_oid(childoid, children)
+	{
+		Relation	childrel = table_open(childoid, NoLock);
+
+		ATExecSetNotNullNoInherit(childrel, NameStr(currcon->conname),
+								  colName, lockmode);
+
+		table_close(childrel, NoLock);
+	}
+
+	heap_freetuple(contuple);
+
+	return address;
+}
+
+/*
+ * Find out the not null constraint from provided relation and decrement the
+ * coninhcount count if constraint exists since the parent constraint marked as
+ * no inherit.
+ *
+ * We must recurse to child tables during execution.
+ */
+static ObjectAddress
+ATExecSetNotNullNoInherit(Relation rel, char *conName,
+						  char *colName, LOCKMODE lockmode)
+{
+
+	HeapTuple	tuple;
+	AttrNumber	attnum;
+	ObjectAddress address;
+	List	   *children;
+
+	/* Guard against stack overflow due to overly deep inheritance tree. */
+	check_stack_depth();
+
+	ATSimplePermissions(AT_AddConstraint, rel,
+						ATT_PARTITIONED_TABLE | ATT_TABLE | ATT_FOREIGN_TABLE);
+
+	attnum = get_attnum(RelationGetRelid(rel), colName);
+	if (attnum == InvalidAttrNumber)
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_COLUMN),
+				 errmsg("column \"%s\" of relation \"%s\" does not exist",
+						colName, RelationGetRelationName(rel))));
+
+	/* Prevent them from altering a system attribute */
+	if (attnum <= 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+				 errmsg("cannot alter system column \"%s\"",
+						colName)));
+
+	/* See if there's already a constraint */
+	tuple = findNotNullConstraintAttnum(RelationGetRelid(rel), attnum);
+	if (HeapTupleIsValid(tuple))
+	{
+		Form_pg_constraint conForm = (Form_pg_constraint) GETSTRUCT(tuple);
+		bool		changed = false;
+
+		/* Decrement the constraint inheritance count */
+		if (conForm->coninhcount > 0)
+		{
+			conForm->coninhcount--;
+			changed = true;
+		}
+		/* Mark the constraint as local defined once coninhcount = 0 */
+		if (conForm->coninhcount == 0)
+		{
+			conForm->conislocal = true;
+			changed = true;
+		}
+
+		if (changed)
+		{
+			Relation	constr_rel;
+
+			constr_rel = table_open(ConstraintRelationId, RowExclusiveLock);
+
+			CatalogTupleUpdate(constr_rel, &tuple->t_self, tuple);
+			ObjectAddressSet(address, ConstraintRelationId, conForm->oid);
+			table_close(constr_rel, RowExclusiveLock);
+
+			/* Make update visible */
+			CommandCounterIncrement();
+		}
+	}
+	else
+		elog(ERROR, "cache lookup failed for not-null constraint on column \"%s\" of relation %u",
+			 colName, RelationGetRelid(rel));
+
+	if (tuple)
+		heap_freetuple(tuple);
+
+	InvokeObjectPostAlterHook(RelationRelationId,
+							  RelationGetRelid(rel), attnum);
+
+	/*
+	 * Recurse to child tables.
+	 */
+	children = find_inheritance_children(RelationGetRelid(rel), lockmode);
+
+	foreach_oid(childoid, children)
+	{
+		Relation	childrel = table_open(childoid, NoLock);
+
+		ATExecSetNotNullNoInherit(childrel, conName, colName, lockmode);
+		table_close(childrel, NoLock);
+	}
+
+	return address;
+}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index d7f9c00..d96989a 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -2669,6 +2669,26 @@ alter_table_cmd:
 									NULL, NULL, NULL, yyscanner);
 					$$ = (Node *) n;
 				}
+			/* ALTER TABLE <name> ALTER CONSTRAINT INHERIT */
+			| ALTER CONSTRAINT name SET INHERIT
+				{
+					AlterTableCmd *n = makeNode(AlterTableCmd);
+
+					n->subtype = AT_AlterConstraintInherit;
+					n->name = $3;
+
+					$$ = (Node *) n;
+				}
+			/* ALTER TABLE <name> ALTER CONSTRAINT SET NO INHERIT */
+			| ALTER CONSTRAINT name SET NO INHERIT
+				{
+					AlterTableCmd *n = makeNode(AlterTableCmd);
+
+					n->subtype = AT_AlterConstraintNoInherit;
+					n->name = $3;
+
+					$$ = (Node *) n;
+				}
 			/* ALTER TABLE <name> VALIDATE CONSTRAINT ... */
 			| VALIDATE CONSTRAINT name
 				{
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index ffe155e..6ba542b 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2467,6 +2467,8 @@ typedef enum AlterTableType
 	AT_SetIdentity,				/* SET identity column options */
 	AT_DropIdentity,			/* DROP IDENTITY */
 	AT_ReAddStatistics,			/* internal to commands/tablecmds.c */
+	AT_AlterConstraintInherit,	/* alter constraint set inherit */
+	AT_AlterConstraintNoInherit, /* alter constraint set no inherit */
 } AlterTableType;
 
 typedef struct ReplicaIdentityStmt
diff --git a/src/test/modules/test_ddl_deparse/test_ddl_deparse.c b/src/test/modules/test_ddl_deparse/test_ddl_deparse.c
index 193669f..46281ec 100644
--- a/src/test/modules/test_ddl_deparse/test_ddl_deparse.c
+++ b/src/test/modules/test_ddl_deparse/test_ddl_deparse.c
@@ -168,6 +168,8 @@ get_altertable_subcmdinfo(PG_FUNCTION_ARGS)
 				strtype = "(re) ADD DOMAIN CONSTRAINT";
 				break;
 			case AT_AlterConstraint:
+			case AT_AlterConstraintInherit:
+			case AT_AlterConstraintNoInherit:
 				strtype = "ALTER CONSTRAINT";
 				break;
 			case AT_ValidateConstraint:
diff --git a/src/test/regress/expected/inherit.out b/src/test/regress/expected/inherit.out
index dbf3835..2d76aba 100644
--- a/src/test/regress/expected/inherit.out
+++ b/src/test/regress/expected/inherit.out
@@ -2744,6 +2744,587 @@ NOTICE:  drop cascades to 2 other objects
 DETAIL:  drop cascades to table inh_multiparent
 drop cascades to table inh_multiparent2
 --
+-- Test - alter constraint inherit/no inherit for not null.
+--
+create table part1 (f1 int not null no inherit);
+create table ch1 (f2 text, f3 int) inherits (part1);
+create table ch2 (f4 float) inherits (part1, ch1);
+NOTICE:  merging multiple inherited definitions of column "f1"
+create table ch3 () inherits (part1, ch1, ch2);
+NOTICE:  merging multiple inherited definitions of column "f1"
+NOTICE:  merging multiple inherited definitions of column "f1"
+NOTICE:  merging multiple inherited definitions of column "f2"
+NOTICE:  merging multiple inherited definitions of column "f3"
+alter table part1 alter constraint part1_f1_not_null set inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+ conrelid |      conname      | contype | coninhcount | conislocal 
+----------+-------------------+---------+-------------+------------
+ part1    | part1_f1_not_null | n       |           0 | t
+ ch1      | part1_f1_not_null | n       |           1 | f
+ ch2      | part1_f1_not_null | n       |           2 | f
+ ch3      | part1_f1_not_null | n       |           3 | f
+(4 rows)
+
+\d+ ch1
+                                    Table "public.ch1"
+ Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+---------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer |           | not null |         | plain    |              | 
+ f2     | text    |           |          |         | extended |              | 
+ f3     | integer |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1" (inherited)
+Inherits: part1
+Child tables: ch2,
+              ch3
+
+\d+ ch2
+                                         Table "public.ch2"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           | not null |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           |          |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1" (inherited)
+Inherits: part1,
+          ch1
+Child tables: ch3
+
+\d+ ch3
+                                         Table "public.ch3"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           | not null |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           |          |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1" (inherited)
+Inherits: part1,
+          ch1,
+          ch2
+
+alter table part1 alter constraint part1_f1_not_null set no inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+ conrelid |      conname      | contype | coninhcount | conislocal 
+----------+-------------------+---------+-------------+------------
+ part1    | part1_f1_not_null | n       |           0 | t
+ ch1      | part1_f1_not_null | n       |           0 | t
+ ch2      | part1_f1_not_null | n       |           0 | t
+ ch3      | part1_f1_not_null | n       |           0 | t
+(4 rows)
+
+\d+ ch1
+                                    Table "public.ch1"
+ Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+---------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer |           | not null |         | plain    |              | 
+ f2     | text    |           |          |         | extended |              | 
+ f3     | integer |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1"
+Inherits: part1
+Child tables: ch2,
+              ch3
+
+\d+ ch2
+                                         Table "public.ch2"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           | not null |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           |          |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1"
+Inherits: part1,
+          ch1
+Child tables: ch3
+
+\d+ ch3
+                                         Table "public.ch3"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           | not null |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           |          |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1"
+Inherits: part1,
+          ch1,
+          ch2
+
+drop table part1 cascade;
+NOTICE:  drop cascades to 3 other objects
+DETAIL:  drop cascades to table ch1
+drop cascades to table ch2
+drop cascades to table ch3
+-- Test inherit constraint and make sure it validates.
+create table part1 (f1 int not null no inherit);
+create table ch1 (f2 text, f3 int) inherits (part1);
+create table ch2 (f4 float) inherits (part1, ch1);
+NOTICE:  merging multiple inherited definitions of column "f1"
+create table ch3 () inherits (part1, ch1, ch2);
+NOTICE:  merging multiple inherited definitions of column "f1"
+NOTICE:  merging multiple inherited definitions of column "f1"
+NOTICE:  merging multiple inherited definitions of column "f2"
+NOTICE:  merging multiple inherited definitions of column "f3"
+insert into ch1 values(NULL, 'sample', 1);
+alter table part1 alter constraint part1_f1_not_null set inherit;
+ERROR:  column "f1" of relation "ch1" contains null values
+delete from ch1;
+alter table part1 alter constraint part1_f1_not_null set inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+ conrelid |      conname      | contype | coninhcount | conislocal 
+----------+-------------------+---------+-------------+------------
+ part1    | part1_f1_not_null | n       |           0 | t
+ ch1      | part1_f1_not_null | n       |           1 | f
+ ch2      | part1_f1_not_null | n       |           2 | f
+ ch3      | part1_f1_not_null | n       |           3 | f
+(4 rows)
+
+\d+ ch1
+                                    Table "public.ch1"
+ Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+---------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer |           | not null |         | plain    |              | 
+ f2     | text    |           |          |         | extended |              | 
+ f3     | integer |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1" (inherited)
+Inherits: part1
+Child tables: ch2,
+              ch3
+
+\d+ ch2
+                                         Table "public.ch2"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           | not null |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           |          |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1" (inherited)
+Inherits: part1,
+          ch1
+Child tables: ch3
+
+\d+ ch3
+                                         Table "public.ch3"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           | not null |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           |          |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1" (inherited)
+Inherits: part1,
+          ch1,
+          ch2
+
+drop table part1 cascade;
+NOTICE:  drop cascades to 3 other objects
+DETAIL:  drop cascades to table ch1
+drop cascades to table ch2
+drop cascades to table ch3
+-- Test not null inherit constraint which already exists on child table.
+create table part1 (f1 int not null no inherit);
+create table ch1 (f2 text, f3 int) inherits (part1);
+create table ch2 (f4 float) inherits (part1, ch1);
+NOTICE:  merging multiple inherited definitions of column "f1"
+alter table ch1 alter f1 set not null;
+\d+ ch1
+                                    Table "public.ch1"
+ Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+---------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer |           | not null |         | plain    |              | 
+ f2     | text    |           |          |         | extended |              | 
+ f3     | integer |           |          |         | plain    |              | 
+Not-null constraints:
+    "ch1_f1_not_null" NOT NULL "f1"
+Inherits: part1
+Child tables: ch2
+
+alter table part1 alter constraint part1_f1_not_null set inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2')
+ order by 2, 1;
+ conrelid |      conname      | contype | coninhcount | conislocal 
+----------+-------------------+---------+-------------+------------
+ ch1      | ch1_f1_not_null   | n       |           1 | t
+ ch2      | ch1_f1_not_null   | n       |           2 | f
+ part1    | part1_f1_not_null | n       |           0 | t
+(3 rows)
+
+\d+ ch1
+                                    Table "public.ch1"
+ Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+---------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer |           | not null |         | plain    |              | 
+ f2     | text    |           |          |         | extended |              | 
+ f3     | integer |           |          |         | plain    |              | 
+Not-null constraints:
+    "ch1_f1_not_null" NOT NULL "f1" (local, inherited)
+Inherits: part1
+Child tables: ch2
+
+\d+ ch2
+                                         Table "public.ch2"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           | not null |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           |          |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "ch1_f1_not_null" NOT NULL "f1" (inherited)
+Inherits: part1,
+          ch1
+
+drop table part1 cascade;
+NOTICE:  drop cascades to 2 other objects
+DETAIL:  drop cascades to table ch1
+drop cascades to table ch2
+create table part1 (f1 int not null no inherit);
+create table ch1 (f2 text, f3 int not null no inherit) inherits (part1);
+create table ch2 (f4 float) inherits (part1, ch1);
+NOTICE:  merging multiple inherited definitions of column "f1"
+alter table ch1 alter constraint ch1_f3_not_null set inherit;
+create table ch3 () inherits (part1, ch1, ch2);
+NOTICE:  merging multiple inherited definitions of column "f1"
+NOTICE:  merging multiple inherited definitions of column "f1"
+NOTICE:  merging multiple inherited definitions of column "f2"
+NOTICE:  merging multiple inherited definitions of column "f3"
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+ conrelid |      conname      | contype | coninhcount | conislocal 
+----------+-------------------+---------+-------------+------------
+ ch1      | ch1_f3_not_null   | n       |           0 | t
+ ch2      | ch1_f3_not_null   | n       |           1 | f
+ ch3      | ch1_f3_not_null   | n       |           2 | f
+ part1    | part1_f1_not_null | n       |           0 | t
+(4 rows)
+
+\d+ ch1
+                                    Table "public.ch1"
+ Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+---------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer |           |          |         | plain    |              | 
+ f2     | text    |           |          |         | extended |              | 
+ f3     | integer |           | not null |         | plain    |              | 
+Not-null constraints:
+    "ch1_f3_not_null" NOT NULL "f3"
+Inherits: part1
+Child tables: ch2,
+              ch3
+
+\d+ ch2
+                                         Table "public.ch2"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           |          |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           | not null |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "ch1_f3_not_null" NOT NULL "f3" (inherited)
+Inherits: part1,
+          ch1
+Child tables: ch3
+
+\d+ ch3
+                                         Table "public.ch3"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           |          |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           | not null |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "ch1_f3_not_null" NOT NULL "f3" (inherited)
+Inherits: part1,
+          ch1,
+          ch2
+
+drop table part1 cascade;
+NOTICE:  drop cascades to 3 other objects
+DETAIL:  drop cascades to table ch1
+drop cascades to table ch2
+drop cascades to table ch3
+-- Multilevel inheritance.
+create table part1 (f1 int not null no inherit);
+create table ch1 (f2 text, f3 int) inherits (part1);
+create table ch2 (f4 float) inherits (ch1);
+create table ch3 () inherits (ch2);
+alter table part1 alter constraint part1_f1_not_null set inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+ conrelid |      conname      | contype | coninhcount | conislocal 
+----------+-------------------+---------+-------------+------------
+ part1    | part1_f1_not_null | n       |           0 | t
+ ch1      | part1_f1_not_null | n       |           1 | f
+ ch2      | part1_f1_not_null | n       |           1 | f
+ ch3      | part1_f1_not_null | n       |           1 | f
+(4 rows)
+
+\d+ ch1
+                                    Table "public.ch1"
+ Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+---------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer |           | not null |         | plain    |              | 
+ f2     | text    |           |          |         | extended |              | 
+ f3     | integer |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1" (inherited)
+Inherits: part1
+Child tables: ch2
+
+\d+ ch2
+                                         Table "public.ch2"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           | not null |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           |          |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1" (inherited)
+Inherits: ch1
+Child tables: ch3
+
+\d+ ch3
+                                         Table "public.ch3"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           | not null |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           |          |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1" (inherited)
+Inherits: ch2
+
+-- Test no inherit.
+alter table part1 alter constraint part1_f1_not_null set no inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+ conrelid |      conname      | contype | coninhcount | conislocal 
+----------+-------------------+---------+-------------+------------
+ part1    | part1_f1_not_null | n       |           0 | t
+ ch1      | part1_f1_not_null | n       |           0 | t
+ ch2      | part1_f1_not_null | n       |           0 | t
+ ch3      | part1_f1_not_null | n       |           0 | t
+(4 rows)
+
+\d+ ch1
+                                    Table "public.ch1"
+ Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+---------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer |           | not null |         | plain    |              | 
+ f2     | text    |           |          |         | extended |              | 
+ f3     | integer |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1"
+Inherits: part1
+Child tables: ch2
+
+\d+ ch2
+                                         Table "public.ch2"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           | not null |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           |          |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1"
+Inherits: ch1
+Child tables: ch3
+
+\d+ ch3
+                                         Table "public.ch3"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           | not null |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           |          |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1"
+Inherits: ch2
+
+drop table part1 cascade;
+NOTICE:  drop cascades to 3 other objects
+DETAIL:  drop cascades to table ch1
+drop cascades to table ch2
+drop cascades to table ch3
+-- If existing behavior is INHERIT.
+create table part1 (f1 int not null);
+create table ch1 (f2 text, f3 int) inherits (part1);
+create table ch2 (f4 float) inherits (ch1);
+create table ch3 () inherits (ch2);
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+ conrelid |      conname      | contype | coninhcount | conislocal 
+----------+-------------------+---------+-------------+------------
+ part1    | part1_f1_not_null | n       |           0 | t
+ ch1      | part1_f1_not_null | n       |           1 | f
+ ch2      | part1_f1_not_null | n       |           1 | f
+ ch3      | part1_f1_not_null | n       |           1 | f
+(4 rows)
+
+alter table part1 alter constraint part1_f1_not_null set inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+ conrelid |      conname      | contype | coninhcount | conislocal 
+----------+-------------------+---------+-------------+------------
+ part1    | part1_f1_not_null | n       |           0 | t
+ ch1      | part1_f1_not_null | n       |           1 | f
+ ch2      | part1_f1_not_null | n       |           1 | f
+ ch3      | part1_f1_not_null | n       |           1 | f
+(4 rows)
+
+-- Set to no inherit.
+alter table part1 alter constraint part1_f1_not_null set no inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+ conrelid |      conname      | contype | coninhcount | conislocal 
+----------+-------------------+---------+-------------+------------
+ part1    | part1_f1_not_null | n       |           0 | t
+ ch1      | part1_f1_not_null | n       |           0 | t
+ ch2      | part1_f1_not_null | n       |           0 | t
+ ch3      | part1_f1_not_null | n       |           0 | t
+(4 rows)
+
+drop table part1 cascade;
+NOTICE:  drop cascades to 3 other objects
+DETAIL:  drop cascades to table ch1
+drop cascades to table ch2
+drop cascades to table ch3
+-- Test no inherit when child has inherited constraint from multiple parents.
+create table part1 (f1 int not null);
+create table ch1 (f2 text, f3 int) inherits (part1);
+create table ch2 (f4 float) inherits (part1, ch1);
+NOTICE:  merging multiple inherited definitions of column "f1"
+create table ch3 () inherits (part1, ch1, ch2);
+NOTICE:  merging multiple inherited definitions of column "f1"
+NOTICE:  merging multiple inherited definitions of column "f1"
+NOTICE:  merging multiple inherited definitions of column "f2"
+NOTICE:  merging multiple inherited definitions of column "f3"
+create table part2(f1 int not null);
+alter table ch2 inherit part2;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+ conrelid |      conname      | contype | coninhcount | conislocal 
+----------+-------------------+---------+-------------+------------
+ part1    | part1_f1_not_null | n       |           0 | t
+ ch1      | part1_f1_not_null | n       |           1 | f
+ ch2      | part1_f1_not_null | n       |           3 | f
+ ch3      | part1_f1_not_null | n       |           3 | f
+(4 rows)
+
+alter table part1 alter constraint part1_f1_not_null set no inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+ conrelid |      conname      | contype | coninhcount | conislocal 
+----------+-------------------+---------+-------------+------------
+ part1    | part1_f1_not_null | n       |           0 | t
+ ch1      | part1_f1_not_null | n       |           0 | t
+ ch2      | part1_f1_not_null | n       |           1 | f
+ ch3      | part1_f1_not_null | n       |           0 | t
+(4 rows)
+
+\d+ ch1
+                                    Table "public.ch1"
+ Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+---------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer |           | not null |         | plain    |              | 
+ f2     | text    |           |          |         | extended |              | 
+ f3     | integer |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1"
+Inherits: part1
+Child tables: ch2,
+              ch3
+
+\d+ ch2
+                                         Table "public.ch2"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           | not null |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           |          |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1" (inherited)
+Inherits: part1,
+          ch1,
+          part2
+Child tables: ch3
+
+\d+ ch3
+                                         Table "public.ch3"
+ Column |       Type       | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------------------+-----------+----------+---------+----------+--------------+-------------
+ f1     | integer          |           | not null |         | plain    |              | 
+ f2     | text             |           |          |         | extended |              | 
+ f3     | integer          |           |          |         | plain    |              | 
+ f4     | double precision |           |          |         | plain    |              | 
+Not-null constraints:
+    "part1_f1_not_null" NOT NULL "f1"
+Inherits: part1,
+          ch1,
+          ch2
+
+drop table part1 cascade;
+NOTICE:  drop cascades to 3 other objects
+DETAIL:  drop cascades to table ch1
+drop cascades to table ch2
+drop cascades to table ch3
+drop table part2 cascade;
+-- Negative scenarios for alter constraint .. set inherit.
+-- Other than not null constraints are not allowed to inherit.
+create table part1 (f1 int check(f1 > 5));
+alter table part1 alter constraint part1_f1_check set inherit;
+ERROR:  ALTER TABLE "part1" ALTER CONSTRAINT "part1_f1_check" SET INHERIT only supports not null constraint
+drop table part1;
+-- error out when provided not null constarint does not exists.
+create table part1(f1 int not null no inherit);
+alter table part1 alter constraint foo set inherit;
+ERROR:  constraint "foo" of relation "part1" does not exist
+drop table part1;
+--
 -- Mixed ownership inheritance tree
 --
 create role regress_alice;
diff --git a/src/test/regress/sql/inherit.sql b/src/test/regress/sql/inherit.sql
index 49aae42..a4e7cb7 100644
--- a/src/test/regress/sql/inherit.sql
+++ b/src/test/regress/sql/inherit.sql
@@ -1091,6 +1091,167 @@ select conrelid::regclass, contype, conname,
 drop table inh_p1, inh_p2, inh_p3, inh_p4 cascade;
 
 --
+-- Test - alter constraint inherit/no inherit for not null.
+--
+create table part1 (f1 int not null no inherit);
+create table ch1 (f2 text, f3 int) inherits (part1);
+create table ch2 (f4 float) inherits (part1, ch1);
+create table ch3 () inherits (part1, ch1, ch2);
+alter table part1 alter constraint part1_f1_not_null set inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+\d+ ch1
+\d+ ch2
+\d+ ch3
+
+alter table part1 alter constraint part1_f1_not_null set no inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+\d+ ch1
+\d+ ch2
+\d+ ch3
+
+drop table part1 cascade;
+
+-- Test inherit constraint and make sure it validates.
+create table part1 (f1 int not null no inherit);
+create table ch1 (f2 text, f3 int) inherits (part1);
+create table ch2 (f4 float) inherits (part1, ch1);
+create table ch3 () inherits (part1, ch1, ch2);
+insert into ch1 values(NULL, 'sample', 1);
+alter table part1 alter constraint part1_f1_not_null set inherit;
+delete from ch1;
+alter table part1 alter constraint part1_f1_not_null set inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+\d+ ch1
+\d+ ch2
+\d+ ch3
+
+drop table part1 cascade;
+
+-- Test not null inherit constraint which already exists on child table.
+create table part1 (f1 int not null no inherit);
+create table ch1 (f2 text, f3 int) inherits (part1);
+create table ch2 (f4 float) inherits (part1, ch1);
+alter table ch1 alter f1 set not null;
+\d+ ch1
+alter table part1 alter constraint part1_f1_not_null set inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2')
+ order by 2, 1;
+\d+ ch1
+\d+ ch2
+
+drop table part1 cascade;
+
+create table part1 (f1 int not null no inherit);
+create table ch1 (f2 text, f3 int not null no inherit) inherits (part1);
+create table ch2 (f4 float) inherits (part1, ch1);
+alter table ch1 alter constraint ch1_f3_not_null set inherit;
+create table ch3 () inherits (part1, ch1, ch2);
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+\d+ ch1
+\d+ ch2
+\d+ ch3
+
+drop table part1 cascade;
+
+-- Multilevel inheritance.
+create table part1 (f1 int not null no inherit);
+create table ch1 (f2 text, f3 int) inherits (part1);
+create table ch2 (f4 float) inherits (ch1);
+create table ch3 () inherits (ch2);
+alter table part1 alter constraint part1_f1_not_null set inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+\d+ ch1
+\d+ ch2
+\d+ ch3
+
+-- Test no inherit.
+alter table part1 alter constraint part1_f1_not_null set no inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+\d+ ch1
+\d+ ch2
+\d+ ch3
+
+drop table part1 cascade;
+
+-- If existing behavior is INHERIT.
+create table part1 (f1 int not null);
+create table ch1 (f2 text, f3 int) inherits (part1);
+create table ch2 (f4 float) inherits (ch1);
+create table ch3 () inherits (ch2);
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+alter table part1 alter constraint part1_f1_not_null set inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+
+-- Set to no inherit.
+alter table part1 alter constraint part1_f1_not_null set no inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+
+drop table part1 cascade;
+
+-- Test no inherit when child has inherited constraint from multiple parents.
+create table part1 (f1 int not null);
+create table ch1 (f2 text, f3 int) inherits (part1);
+create table ch2 (f4 float) inherits (part1, ch1);
+create table ch3 () inherits (part1, ch1, ch2);
+create table part2(f1 int not null);
+alter table ch2 inherit part2;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+alter table part1 alter constraint part1_f1_not_null set no inherit;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('part1', 'ch1', 'ch2', 'ch3')
+ order by 2, 1;
+\d+ ch1
+\d+ ch2
+\d+ ch3
+
+drop table part1 cascade;
+drop table part2 cascade;
+
+-- Negative scenarios for alter constraint .. set inherit.
+-- Other than not null constraints are not allowed to inherit.
+create table part1 (f1 int check(f1 > 5));
+alter table part1 alter constraint part1_f1_check set inherit;
+drop table part1;
+
+-- error out when provided not null constarint does not exists.
+create table part1(f1 int not null no inherit);
+alter table part1 alter constraint foo set inherit;
+drop table part1;
+
+--
 -- Mixed ownership inheritance tree
 --
 create role regress_alice;
