/*
     * Re-parse the index and constraint definitions, and attach them to the
     * appropriate work queue entries.  We do this before dropping because in
-    * the case of a FOREIGN KEY constraint, we might not yet have exclusive
-    * lock on the table the constraint is attached to, and we need to get
-    * that before reparsing/dropping.
+    * the case of a constraint on another table, we might not yet have
+    * exclusive lock on the table the constraint is attached to, and we need
+    * to get that before reparsing/dropping.  (That's possible at least for
+    * FOREIGN KEY, CHECK, and EXCLUSION constraints; in non-FK cases it
+    * requires a dependency on the target table's composite type in the other
+    * table's constraint expressions.)
     *
     * We can't rely on the output of deparsing to tell us which relation to
     * operate on, because concurrent activity might have made the name
        Form_pg_constraint con;
        Oid         relid;
        Oid         confrelid;
-       char        contype;
        bool        conislocal;
 
        tup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(oldId));
                elog(ERROR, "could not identify relation associated with constraint %u", oldId);
        }
        confrelid = con->confrelid;
-       contype = con->contype;
        conislocal = con->conislocal;
        ReleaseSysCache(tup);
 
            continue;
 
        /*
-        * When rebuilding an FK constraint that references the table we're
-        * modifying, we might not yet have any lock on the FK's table, so get
-        * one now.  We'll need AccessExclusiveLock for the DROP CONSTRAINT
-        * step, so there's no value in asking for anything weaker.
+        * When rebuilding another table's constraint that references the
+        * table we're modifying, we might not yet have any lock on the other
+        * table, so get one now.  We'll need AccessExclusiveLock for the DROP
+        * CONSTRAINT step, so there's no value in asking for anything weaker.
         */
-       if (relid != tab->relid && contype == CONSTRAINT_FOREIGN)
+       if (relid != tab->relid)
            LockRelationOid(relid, AccessExclusiveLock);
 
        ATPostAlterTypeParse(oldId, relid, confrelid,
 
 alter table atref alter column c1 set data type bigint;
 drop table attbl, atref;
 /* End test case for bug #17409 */
+/* Test case for bug #18970 */
+create table attbl(a int);
+create table atref(b attbl check ((b).a is not null));
+alter table attbl alter column a type numeric;  -- someday this should work
+ERROR:  cannot alter table "attbl" because column "atref.b" uses its row type
+drop table attbl, atref;
+/* End test case for bug #18970 */
 -- Test that ALTER TABLE rewrite preserves a clustered index
 -- for normal indexes and indexes on constraints.
 create table alttype_cluster (a int);
 
 
 /* End test case for bug #17409 */
 
+/* Test case for bug #18970 */
+
+create table attbl(a int);
+create table atref(b attbl check ((b).a is not null));
+alter table attbl alter column a type numeric;  -- someday this should work
+drop table attbl, atref;
+
+/* End test case for bug #18970 */
+
 -- Test that ALTER TABLE rewrite preserves a clustered index
 -- for normal indexes and indexes on constraints.
 create table alttype_cluster (a int);