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 ]
<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>
+ These forms modify 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
+ will be 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>
static void AlterSeqNamespaces(Relation classRel, Relation rel,
Oid oldNspOid, Oid newNspOid, ObjectAddresses *objsMoved,
LOCKMODE lockmode);
-static ObjectAddress ATExecAlterConstraint(Relation rel, ATAlterConstraint *cmdcon,
+static ObjectAddress ATExecAlterConstraint(List **wqueue, Relation rel,
+ ATAlterConstraint *cmdcon,
bool recurse, LOCKMODE lockmode);
-static bool ATExecAlterConstraintInternal(ATAlterConstraint *cmdcon, Relation conrel,
+static bool ATExecAlterConstraintInternal(List **wqueue, ATAlterConstraint *cmdcon, Relation conrel,
Relation tgrel, Relation rel, HeapTuple contuple,
bool recurse, List **otherrelids, LOCKMODE lockmode);
static void AlterConstrTriggerDeferrability(Oid conoid, Relation tgrel, Relation rel,
lockmode);
break;
case AT_AlterConstraint: /* ALTER CONSTRAINT */
- address = ATExecAlterConstraint(rel, castNode(ATAlterConstraint,
- cmd->def),
+ address = ATExecAlterConstraint(wqueue, rel,
+ castNode(ATAlterConstraint, cmd->def),
cmd->recurse, lockmode);
break;
case AT_ValidateConstraint: /* VALIDATE CONSTRAINT */
*
* Update the attributes of a constraint.
*
- * Currently only works for Foreign Key constraints.
+ * Currently only works for Foreign Key and not null constraints.
*
* If the constraint is modified, returns its address; otherwise, return
* InvalidObjectAddress.
*/
static ObjectAddress
-ATExecAlterConstraint(Relation rel, ATAlterConstraint *cmdcon, bool recurse,
- LOCKMODE lockmode)
+ATExecAlterConstraint(List **wqueue, Relation rel, ATAlterConstraint *cmdcon,
+ bool recurse, LOCKMODE lockmode)
{
Relation conrel;
Relation tgrel;
cmdcon->conname, RelationGetRelationName(rel))));
currcon = (Form_pg_constraint) GETSTRUCT(contuple);
- if (currcon->contype != CONSTRAINT_FOREIGN)
+ if (cmdcon->alterDeferrability && currcon->contype != CONSTRAINT_FOREIGN)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("constraint \"%s\" of relation \"%s\" is not a foreign key constraint",
cmdcon->conname, RelationGetRelationName(rel))));
+ if (cmdcon->alterInheritability &&
+ currcon->contype != CONSTRAINT_NOTNULL)
+ ereport(ERROR,
+ errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("constraint \"%s\" of relation \"%s\" is not a not-null constraint",
+ cmdcon->conname, RelationGetRelationName(rel)));
+
+ /* Refuse to modify inheritability of inherited constraints */
+ if (cmdcon->alterInheritability &&
+ cmdcon->noinherit && currcon->coninhcount > 0)
+ ereport(ERROR,
+ errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("cannot alter inherited constraint \"%s\" on relation \"%s\"",
+ NameStr(currcon->conname),
+ RelationGetRelationName(rel)));
/*
* If it's not the topmost constraint, raise an error.
/*
* Do the actual catalog work, and recurse if necessary.
*/
- if (ATExecAlterConstraintInternal(cmdcon, conrel, tgrel, rel, contuple,
- recurse, &otherrelids, lockmode))
+ if (ATExecAlterConstraintInternal(wqueue, cmdcon, conrel, tgrel, rel,
+ contuple, recurse, &otherrelids, lockmode))
ObjectAddressSet(address, ConstraintRelationId, currcon->oid);
/*
* but existing releases don't do that.)
*/
static bool
-ATExecAlterConstraintInternal(ATAlterConstraint *cmdcon, Relation conrel,
- Relation tgrel, Relation rel, HeapTuple contuple,
- bool recurse, List **otherrelids, LOCKMODE lockmode)
+ATExecAlterConstraintInternal(List **wqueue, ATAlterConstraint *cmdcon,
+ Relation conrel, Relation tgrel, Relation rel,
+ HeapTuple contuple, bool recurse,
+ List **otherrelids, LOCKMODE lockmode)
{
Form_pg_constraint currcon;
Oid refrelid = InvalidOid;
Relation childrel;
childrel = table_open(childcon->conrelid, lockmode);
- ATExecAlterConstraintInternal(cmdcon, conrel, tgrel, childrel, childtup,
- recurse, otherrelids, lockmode);
+ ATExecAlterConstraintInternal(wqueue, cmdcon, conrel, tgrel, childrel,
+ childtup, recurse, otherrelids, lockmode);
table_close(childrel, NoLock);
}
systable_endscan(pscan);
}
+ /*
+ * Update the catalog for inheritability. No work if the constraint is
+ * already in the requested state.
+ */
+ if (cmdcon->alterInheritability &&
+ (cmdcon->noinherit != currcon->connoinherit))
+ {
+ AttrNumber colNum;
+ char *colName;
+ List *children;
+ HeapTuple copyTuple;
+ Form_pg_constraint copy_con;
+
+ /* The current implementation only works for NOT NULL constraints */
+ Assert(currcon->contype == CONSTRAINT_NOTNULL);
+
+ copyTuple = heap_copytuple(contuple);
+ copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple);
+ copy_con->connoinherit = cmdcon->noinherit;
+
+ CatalogTupleUpdate(conrel, ©Tuple->t_self, copyTuple);
+ CommandCounterIncrement();
+ heap_freetuple(copyTuple);
+ changed = true;
+
+ /* Fetch the column number and name */
+ colNum = extractNotNullColumn(contuple);
+ colName = get_attname(currcon->conrelid, colNum, false);
+
+ /*
+ * Propagate the change to children. For SET NO INHERIT, we don't
+ * recursively affect children, just the immediate level.
+ */
+ children = find_inheritance_children(RelationGetRelid(rel),
+ lockmode);
+ foreach_oid(childoid, children)
+ {
+ ObjectAddress addr;
+
+ if (cmdcon->noinherit)
+ {
+ HeapTuple childtup;
+ Form_pg_constraint childcon;
+
+ childtup = findNotNullConstraint(childoid, colName);
+ if (!childtup)
+ elog(ERROR, "cache lookup failed for not-null constraint on column \"%s\" of relation %u",
+ colName, childoid);
+ childcon = (Form_pg_constraint) GETSTRUCT(childtup);
+ Assert(childcon->coninhcount > 0);
+ childcon->coninhcount--;
+ childcon->conislocal = true;
+ CatalogTupleUpdate(conrel, &childtup->t_self, childtup);
+ heap_freetuple(childtup);
+ }
+ else
+ {
+ Relation childrel = table_open(childoid, NoLock);
+
+ addr = ATExecSetNotNull(wqueue, childrel, NameStr(currcon->conname),
+ colName, true, true, lockmode);
+ if (OidIsValid(addr.objectId))
+ CommandCounterIncrement();
+ table_close(childrel, NoLock);
+ }
+ }
+ }
+
return changed;
}
NULL, NULL, NULL, yyscanner);
$$ = (Node *) n;
}
+ /* ALTER TABLE <name> ALTER CONSTRAINT SET INHERIT */
+ | ALTER CONSTRAINT name SET INHERIT
+ {
+ AlterTableCmd *n = makeNode(AlterTableCmd);
+ ATAlterConstraint *c = makeNode(ATAlterConstraint);
+
+ n->subtype = AT_AlterConstraint;
+ n->def = (Node *) c;
+ c->conname = $3;
+ c->alterInheritability = true;
+ c->noinherit = false;
+
+ $$ = (Node *) n;
+ }
+ /* ALTER TABLE <name> ALTER CONSTRAINT SET NO INHERIT */
+ | ALTER CONSTRAINT name SET NO INHERIT
+ {
+ AlterTableCmd *n = makeNode(AlterTableCmd);
+ ATAlterConstraint *c = makeNode(ATAlterConstraint);
+
+ n->subtype = AT_AlterConstraint;
+ n->def = (Node *) c;
+ c->conname = $3;
+ c->alterInheritability = true;
+ c->noinherit = true;
+
+ $$ = (Node *) n;
+ }
/* ALTER TABLE <name> VALIDATE CONSTRAINT ... */
| VALIDATE CONSTRAINT name
{
bool alterDeferrability; /* changing deferrability properties? */
bool deferrable; /* DEFERRABLE? */
bool initdeferred; /* INITIALLY DEFERRED? */
+ bool alterInheritability; /* changing inheritability properties */
+ bool noinherit;
} ATAlterConstraint;
/* Ad-hoc node for AT_ReplicaIdentity */
ERROR: conflicting NO INHERIT declaration for not-null constraint on column "a"
CREATE TABLE inh_nn4 (a int not null no inherit, b int, not null a);
ERROR: conflicting NO INHERIT declaration for not-null constraint on column "a"
-DROP TABLE inh_nn1, inh_nn2, inh_nn3, inh_nn4;
-ERROR: table "inh_nn2" does not exist
+DROP TABLE IF EXISTS inh_nn1, inh_nn2, inh_nn3, inh_nn4;
+NOTICE: table "inh_nn2" does not exist, skipping
+NOTICE: table "inh_nn3" does not exist, skipping
+NOTICE: table "inh_nn4" does not exist, skipping
--
-- test inherit/deinherit
--
DETAIL: drop cascades to table inh_multiparent
drop cascades to table inh_multiparent2
--
+-- Test ALTER CONSTRAINT SET [NO] INHERIT
+--
+create table inh_nn1 (f1 int not null no inherit);
+create table inh_nn2 (f2 text, f3 int, f1 int);
+alter table inh_nn2 inherit inh_nn1;
+create table inh_nn3 (f4 float) inherits (inh_nn2);
+create table inh_nn4 (f5 int, f4 float, f2 text, f3 int, f1 int);
+alter table inh_nn4 inherit inh_nn2, inherit inh_nn1, inherit inh_nn3;
+alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit;
+select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4')
+ order by 2, 1;
+ conrelid | conname | conkey | coninhcount | conislocal | connoinherit
+----------+---------------------+--------+-------------+------------+--------------
+ inh_nn1 | inh_nn1_f1_not_null | {1} | 0 | t | f
+ inh_nn2 | inh_nn1_f1_not_null | {3} | 1 | f | f
+ inh_nn3 | inh_nn1_f1_not_null | {3} | 1 | f | f
+ inh_nn4 | inh_nn1_f1_not_null | {5} | 3 | f | f
+(4 rows)
+
+-- ALTER CONSTRAINT SET NO INHERIT should work on top-level constraints
+alter table inh_nn1 alter constraint inh_nn1_f1_not_null set no inherit;
+select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4')
+ order by 2, 1;
+ conrelid | conname | conkey | coninhcount | conislocal | connoinherit
+----------+---------------------+--------+-------------+------------+--------------
+ inh_nn1 | inh_nn1_f1_not_null | {1} | 0 | t | t
+ inh_nn2 | inh_nn1_f1_not_null | {3} | 0 | t | f
+ inh_nn3 | inh_nn1_f1_not_null | {3} | 1 | f | f
+ inh_nn4 | inh_nn1_f1_not_null | {5} | 2 | t | f
+(4 rows)
+
+-- A constraint that's NO INHERIT can be dropped without damaging children
+alter table inh_nn1 drop constraint inh_nn1_f1_not_null;
+select conrelid::regclass, conname, coninhcount, conislocal, connoinherit
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4')
+ order by 2, 1;
+ conrelid | conname | coninhcount | conislocal | connoinherit
+----------+---------------------+-------------+------------+--------------
+ inh_nn2 | inh_nn1_f1_not_null | 0 | t | f
+ inh_nn3 | inh_nn1_f1_not_null | 1 | f | f
+ inh_nn4 | inh_nn1_f1_not_null | 2 | t | f
+(3 rows)
+
+drop table inh_nn1, inh_nn2, inh_nn3, inh_nn4;
+-- Test inherit constraint and make sure it validates.
+create table inh_nn1 (f1 int not null no inherit);
+create table inh_nn2 (f2 text, f3 int) inherits (inh_nn1);
+insert into inh_nn2 values(NULL, 'sample', 1);
+alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit;
+ERROR: column "f1" of relation "inh_nn2" contains null values
+delete from inh_nn2;
+create table inh_nn3 () inherits (inh_nn2);
+create table inh_nn4 () inherits (inh_nn1, inh_nn2);
+NOTICE: merging multiple inherited definitions of column "f1"
+alter table inh_nn1 -- test multicommand alter table while at it
+ alter constraint inh_nn1_f1_not_null set inherit,
+ alter constraint inh_nn1_f1_not_null set no inherit;
+select conrelid::regclass, conname, coninhcount, conislocal, connoinherit
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4')
+ order by 2, 1;
+ conrelid | conname | coninhcount | conislocal | connoinherit
+----------+---------------------+-------------+------------+--------------
+ inh_nn1 | inh_nn1_f1_not_null | 0 | t | t
+ inh_nn2 | inh_nn1_f1_not_null | 0 | t | f
+ inh_nn3 | inh_nn1_f1_not_null | 1 | f | f
+ inh_nn4 | inh_nn1_f1_not_null | 1 | t | f
+(4 rows)
+
+drop table inh_nn1, inh_nn2, inh_nn3, inh_nn4;
+-- Test not null inherit constraint which already exists on child table.
+create table inh_nn1 (f1 int not null no inherit);
+create table inh_nn2 (f2 text, f3 int) inherits (inh_nn1);
+create table inh_nn3 (f4 float, constraint nn3_f1 not null f1 no inherit) inherits (inh_nn1, inh_nn2);
+NOTICE: merging multiple inherited definitions of column "f1"
+select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3')
+ order by 2, 1;
+ conrelid | conname | conkey | coninhcount | conislocal | connoinherit
+----------+---------------------+--------+-------------+------------+--------------
+ inh_nn1 | inh_nn1_f1_not_null | {1} | 0 | t | t
+ inh_nn3 | nn3_f1 | {1} | 0 | t | t
+(2 rows)
+
+-- error: inh_nn3 has an incompatible NO INHERIT constraint
+alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit;
+ERROR: cannot change NO INHERIT status of NOT NULL constraint "nn3_f1" on relation "inh_nn3"
+alter table inh_nn3 alter constraint nn3_f1 set inherit;
+alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit; -- now it works
+select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3')
+ order by 2, 1;
+ conrelid | conname | conkey | coninhcount | conislocal | connoinherit
+----------+---------------------+--------+-------------+------------+--------------
+ inh_nn1 | inh_nn1_f1_not_null | {1} | 0 | t | f
+ inh_nn2 | inh_nn1_f1_not_null | {1} | 1 | f | f
+ inh_nn3 | nn3_f1 | {1} | 2 | t | f
+(3 rows)
+
+drop table inh_nn1, inh_nn2, inh_nn3;
+-- Negative scenarios for alter constraint .. set inherit.
+create table inh_nn1 (f1 int check(f1 > 5) primary key references inh_nn1, f2 int not null);
+-- constraints other than not-null are not supported
+alter table inh_nn1 alter constraint inh_nn1_f1_check set inherit;
+ERROR: constraint "inh_nn1_f1_check" of relation "inh_nn1" is not a not-null constraint
+alter table inh_nn1 alter constraint inh_nn1_pkey set inherit;
+ERROR: constraint "inh_nn1_pkey" of relation "inh_nn1" is not a not-null constraint
+alter table inh_nn1 alter constraint inh_nn1_f1_fkey set inherit;
+ERROR: constraint "inh_nn1_f1_fkey" of relation "inh_nn1" is not a not-null constraint
+-- try to drop a nonexistant constraint
+alter table inh_nn1 alter constraint foo set inherit;
+ERROR: constraint "foo" of relation "inh_nn1" does not exist
+-- Can't modify inheritability of inherited constraints
+create table inh_nn2 () inherits (inh_nn1);
+alter table inh_nn2 alter constraint inh_nn1_f2_not_null set no inherit;
+ERROR: cannot alter inherited constraint "inh_nn1_f2_not_null" on relation "inh_nn2"
+drop table inh_nn1, inh_nn2;
+--
-- Mixed ownership inheritance tree
--
create role regress_alice;
CREATE TABLE inh_nn2 (a int not null no inherit) INHERITS (inh_nn1);
CREATE TABLE inh_nn3 (a int not null, b int, not null a no inherit);
CREATE TABLE inh_nn4 (a int not null no inherit, b int, not null a);
-DROP TABLE inh_nn1, inh_nn2, inh_nn3, inh_nn4;
+DROP TABLE IF EXISTS inh_nn1, inh_nn2, inh_nn3, inh_nn4;
--
-- test inherit/deinherit
drop table inh_p1, inh_p2, inh_p3, inh_p4 cascade;
+--
+-- Test ALTER CONSTRAINT SET [NO] INHERIT
+--
+create table inh_nn1 (f1 int not null no inherit);
+create table inh_nn2 (f2 text, f3 int, f1 int);
+alter table inh_nn2 inherit inh_nn1;
+create table inh_nn3 (f4 float) inherits (inh_nn2);
+create table inh_nn4 (f5 int, f4 float, f2 text, f3 int, f1 int);
+alter table inh_nn4 inherit inh_nn2, inherit inh_nn1, inherit inh_nn3;
+alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit;
+select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4')
+ order by 2, 1;
+-- ALTER CONSTRAINT SET NO INHERIT should work on top-level constraints
+alter table inh_nn1 alter constraint inh_nn1_f1_not_null set no inherit;
+select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4')
+ order by 2, 1;
+-- A constraint that's NO INHERIT can be dropped without damaging children
+alter table inh_nn1 drop constraint inh_nn1_f1_not_null;
+select conrelid::regclass, conname, coninhcount, conislocal, connoinherit
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4')
+ order by 2, 1;
+drop table inh_nn1, inh_nn2, inh_nn3, inh_nn4;
+
+-- Test inherit constraint and make sure it validates.
+create table inh_nn1 (f1 int not null no inherit);
+create table inh_nn2 (f2 text, f3 int) inherits (inh_nn1);
+insert into inh_nn2 values(NULL, 'sample', 1);
+alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit;
+delete from inh_nn2;
+create table inh_nn3 () inherits (inh_nn2);
+create table inh_nn4 () inherits (inh_nn1, inh_nn2);
+alter table inh_nn1 -- test multicommand alter table while at it
+ alter constraint inh_nn1_f1_not_null set inherit,
+ alter constraint inh_nn1_f1_not_null set no inherit;
+select conrelid::regclass, conname, coninhcount, conislocal, connoinherit
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4')
+ order by 2, 1;
+drop table inh_nn1, inh_nn2, inh_nn3, inh_nn4;
+
+-- Test not null inherit constraint which already exists on child table.
+create table inh_nn1 (f1 int not null no inherit);
+create table inh_nn2 (f2 text, f3 int) inherits (inh_nn1);
+create table inh_nn3 (f4 float, constraint nn3_f1 not null f1 no inherit) inherits (inh_nn1, inh_nn2);
+select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3')
+ order by 2, 1;
+-- error: inh_nn3 has an incompatible NO INHERIT constraint
+alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit;
+alter table inh_nn3 alter constraint nn3_f1 set inherit;
+alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit; -- now it works
+select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit
+ from pg_constraint where contype = 'n' and
+ conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3')
+ order by 2, 1;
+drop table inh_nn1, inh_nn2, inh_nn3;
+
+-- Negative scenarios for alter constraint .. set inherit.
+create table inh_nn1 (f1 int check(f1 > 5) primary key references inh_nn1, f2 int not null);
+-- constraints other than not-null are not supported
+alter table inh_nn1 alter constraint inh_nn1_f1_check set inherit;
+alter table inh_nn1 alter constraint inh_nn1_pkey set inherit;
+alter table inh_nn1 alter constraint inh_nn1_f1_fkey set inherit;
+-- try to drop a nonexistant constraint
+alter table inh_nn1 alter constraint foo set inherit;
+-- Can't modify inheritability of inherited constraints
+create table inh_nn2 () inherits (inh_nn1);
+alter table inh_nn2 alter constraint inh_nn1_f2_not_null set no inherit;
+
+drop table inh_nn1, inh_nn2;
+
--
-- Mixed ownership inheritance tree
--