</entry>
      </row>
 
+     <row>
+      <entry><structfield>conisonly</structfield></entry>
+      <entry><type>bool</type></entry>
+      <entry></entry>
+      <entry>
+       This constraint is defined locally for the relation.  It is a
+       non-inheritable constraint.
+      </entry>
+     </row>
+
      <row>
       <entry><structfield>conkey</structfield></entry>
       <entry><type>int2[]</type></entry>
 
 </programlisting>
   </para>
 
+  <para>
+   To add a check constraint only to a table and not to its children:
+<programlisting>
+ALTER TABLE ONLY distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5);
+</programlisting>
+   (The check constraint will not be inherited by future children, either.)
+  </para>
+
   <para>
    To remove a check constraint from a table and all its children:
 <programlisting>
 
                   Oid new_array_type);
 static void RelationRemoveInheritance(Oid relid);
 static void StoreRelCheck(Relation rel, char *ccname, Node *expr,
-             bool is_validated, bool is_local, int inhcount);
+             bool is_validated, bool is_local, int inhcount, bool is_only);
 static void StoreConstraints(Relation rel, List *cooked_constraints);
 static bool MergeWithExistingConstraint(Relation rel, char *ccname, Node *expr,
-                           bool allow_merge, bool is_local);
+                           bool allow_merge, bool is_local, bool is_only);
 static void SetRelationNumChecks(Relation rel, int numchecks);
 static Node *cookConstraint(ParseState *pstate,
               Node *raw_constraint,
  */
 static void
 StoreRelCheck(Relation rel, char *ccname, Node *expr,
-             bool is_validated, bool is_local, int inhcount)
+             bool is_validated, bool is_local, int inhcount, bool is_only)
 {
    char       *ccbin;
    char       *ccsrc;
                          ccbin,    /* Binary form of check constraint */
                          ccsrc,    /* Source form of check constraint */
                          is_local,     /* conislocal */
-                         inhcount);    /* coninhcount */
+                         inhcount,     /* coninhcount */
+                         is_only);     /* conisonly */
 
    pfree(ccbin);
    pfree(ccsrc);
                break;
            case CONSTR_CHECK:
                StoreRelCheck(rel, con->name, con->expr, !con->skip_validation,
-                             con->is_local, con->inhcount);
+                             con->is_local, con->inhcount, con->is_only);
                numchecks++;
                break;
            default:
                          List *newColDefaults,
                          List *newConstraints,
                          bool allow_merge,
-                         bool is_local)
+                         bool is_local,
+                         bool is_only)
 {
    List       *cookedConstraints = NIL;
    TupleDesc   tupleDesc;
        cooked->skip_validation = false;
        cooked->is_local = is_local;
        cooked->inhcount = is_local ? 0 : 1;
+       cooked->is_only = is_only;
        cookedConstraints = lappend(cookedConstraints, cooked);
    }
 
             * what ATAddCheckConstraint wants.)
             */
            if (MergeWithExistingConstraint(rel, ccname, expr,
-                                           allow_merge, is_local))
+                               allow_merge, is_local, is_only))
                continue;
        }
        else
         * OK, store it.
         */
        StoreRelCheck(rel, ccname, expr, !cdef->skip_validation, is_local,
-                     is_local ? 0 : 1);
+                     is_local ? 0 : 1, is_only);
 
        numchecks++;
 
        cooked->skip_validation = cdef->skip_validation;
        cooked->is_local = is_local;
        cooked->inhcount = is_local ? 0 : 1;
+       cooked->is_only = is_only;
        cookedConstraints = lappend(cookedConstraints, cooked);
    }
 
  */
 static bool
 MergeWithExistingConstraint(Relation rel, char *ccname, Node *expr,
-                           bool allow_merge, bool is_local)
+                           bool allow_merge, bool is_local,
+                           bool is_only)
 {
    bool        found;
    Relation    conDesc;
                con->conislocal = true;
            else
                con->coninhcount++;
+           if (is_only)
+           {
+               Assert(is_local);
+               con->conisonly = true;
+           }
            simple_heap_update(conDesc, &tup->t_self, tup);
            CatalogUpdateIndexes(conDesc, tup);
            break;
 
                                   NULL,
                                   NULL,
                                   true,        /* islocal */
-                                  0);  /* inhcount */
+                                  0,           /* inhcount */
+                                  false);      /* isonly */
 
    /*
     * Register the index as internally dependent on the constraint.
 
                      const char *conBin,
                      const char *conSrc,
                      bool conIsLocal,
-                     int conInhCount)
+                     int conInhCount,
+                     bool conIsOnly)
 {
    Relation    conDesc;
    Oid         conOid;
    values[Anum_pg_constraint_confmatchtype - 1] = CharGetDatum(foreignMatchType);
    values[Anum_pg_constraint_conislocal - 1] = BoolGetDatum(conIsLocal);
    values[Anum_pg_constraint_coninhcount - 1] = Int32GetDatum(conInhCount);
+   values[Anum_pg_constraint_conisonly - 1] = BoolGetDatum(conIsOnly);
 
    if (conkeyArray)
        values[Anum_pg_constraint_conkey - 1] = PointerGetDatum(conkeyArray);
 
            cooked->skip_validation = false;
            cooked->is_local = true;    /* not used for defaults */
            cooked->inhcount = 0;       /* ditto */
+           cooked->is_only = false;
            cookedDefaults = lappend(cookedDefaults, cooked);
            descriptor->attrs[attnum - 1]->atthasdef = true;
        }
     */
    if (rawDefaults || stmt->constraints)
        AddRelationNewConstraints(rel, rawDefaults, stmt->constraints,
-                                 true, true);
+                                 true, true, false);
 
    /*
     * Clean up.  We keep lock on new relation (although it shouldn't be
                char       *name = check[i].ccname;
                Node       *expr;
 
+               /* ignore if the constraint is non-inheritable */
+               if (check[i].cconly)
+                   continue;
+
                /* adjust varattnos of ccbin here */
                expr = stringToNode(check[i].ccbin);
                change_varattnos_of_a_node(expr, newattno);
                    cooked->skip_validation = false;
                    cooked->is_local = false;
                    cooked->inhcount = 1;
+                   cooked->is_only = false;
                    constraints = lappend(constraints, cooked);
                }
            }
         * This function is intended for CREATE TABLE, so it processes a
         * _list_ of defaults, but we just do one.
         */
-       AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, false, true);
+       AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, false, true, false);
 
        /* Make the additional catalog changes visible */
        CommandCounterIncrement();
         * This function is intended for CREATE TABLE, so it processes a
         * _list_ of defaults, but we just do one.
         */
-       AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, false, true);
+       AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, false, true, false);
    }
 }
 
     * omitted from the returned list, which is what we want: we do not need
     * to do any validation work.  That can only happen at child tables,
     * though, since we disallow merging at the top level.
+    *
+    * Note: we set is_only based on the recurse flag which is false when
+    * interpretInhOption() of our statement returns false all the way up
+    * in AlterTable and gets passed all the way down to here.
     */
    newcons = AddRelationNewConstraints(rel, NIL,
                                        list_make1(copyObject(constr)),
-                                       recursing, !recursing);
+                                       recursing, /* allow_merge */
+                                       !recursing, /* is_local */
+                                       !recurse && !recursing); /* is_only */
 
    /* Add each to-be-validated constraint to Phase 3's queue */
    foreach(lcon, newcons)
    if (newcons == NIL)
        return;
 
+   /*
+    * Adding an ONLY constraint? No need to find our children
+    */
+   if (!recurse && !recursing)
+       return;
+
    /*
     * Propagate to children as appropriate.  Unlike most other ALTER
     * routines, we have to do this one level of recursion at a time; we can't
     */
    children = find_inheritance_children(RelationGetRelid(rel), lockmode);
 
-   /*
-    * If we are told not to recurse, there had better not be any child
-    * tables; else the addition would put them out of step.
-    */
-   if (children && !recurse)
-       ereport(ERROR,
-               (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
-                errmsg("constraint must be added to child tables too")));
-
    foreach(child, children)
    {
        Oid         childrelid = lfirst_oid(child);
                                      NULL,
                                      NULL,
                                      true,     /* islocal */
-                                     0);       /* inhcount */
+                                     0,        /* inhcount */
+                                     false);   /* isonly */
 
    /*
     * Create the triggers that will enforce the constraint.
    HeapTuple   tuple;
    bool        found = false;
    bool        is_check_constraint = false;
+   bool        is_only_constraint = false;
 
    /* At top level, permission check was done in ATPrepCmd, else do it */
    if (recursing)
        /* Right now only CHECK constraints can be inherited */
        if (con->contype == CONSTRAINT_CHECK)
            is_check_constraint = true;
+       
+       if (con->conisonly)
+       {
+           Assert(is_check_constraint);
+           is_only_constraint = true;
+       }
 
        /*
         * Perform the actual constraint deletion
        performDeletion(&conobj, behavior);
 
        found = true;
+
+       /* constraint found and dropped -- no need to keep looping */
+       break;
    }
 
    systable_endscan(scan);
     * routines, we have to do this one level of recursion at a time; we can't
     * use find_all_inheritors to do it in one pass.
     */
-   if (is_check_constraint)
+   if (is_check_constraint && !is_only_constraint)
        children = find_inheritance_children(RelationGetRelid(rel), lockmode);
    else
        children = NIL;
 
                                              NULL,
                                              NULL,
                                              true,     /* islocal */
-                                             0);       /* inhcount */
+                                             0,        /* inhcount */
+                                             false);   /* isonly */
    }
 
    /*
 
                          ccbin,    /* Binary form of check constraint */
                          ccsrc,    /* Source form of check constraint */
                          true, /* is local */
-                         0);   /* inhcount */
+                         0,    /* inhcount */
+                         false);   /* is only */
 
    /*
     * Return the compiled constraint expression so the calling routine can
 
                 RelationGetRelationName(relation));
 
        check[found].ccvalid = conform->convalidated;
+       check[found].cconly = conform->conisonly;
        check[found].ccname = MemoryContextStrdup(CacheMemoryContext,
                                                  NameStr(conform->conname));
 
 
                          tbinfo->dobj.name);
 
            resetPQExpBuffer(q);
-           if (g_fout->remoteVersion >= 90100)
+           if (g_fout->remoteVersion >= 90200)
            {
+               /*
+                * conisonly and convalidated are new in 9.2 (actually, the latter
+                * is there in 9.1, but it wasn't ever false for check constraints
+                * until 9.2).
+                */
                appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
                           "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
-                                 "conislocal, convalidated "
+                                 "conislocal, convalidated, conisonly "
                                  "FROM pg_catalog.pg_constraint "
                                  "WHERE conrelid = '%u'::pg_catalog.oid "
                                  "   AND contype = 'c' "
            {
                appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
                           "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
-                                 "conislocal, true AS convalidated "
+                                 "conislocal, true AS convalidated, "
+                                 "false as conisonly "
                                  "FROM pg_catalog.pg_constraint "
                                  "WHERE conrelid = '%u'::pg_catalog.oid "
                                  "   AND contype = 'c' "
            {
                appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
                           "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
-                                 "true AS conislocal, true AS convalidated "
+                                 "true AS conislocal, true AS convalidated, "
+                                 "false as conisonly "
                                  "FROM pg_catalog.pg_constraint "
                                  "WHERE conrelid = '%u'::pg_catalog.oid "
                                  "   AND contype = 'c' "
                /* no pg_get_constraintdef, must use consrc */
                appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
                                  "'CHECK (' || consrc || ')' AS consrc, "
-                                 "true AS conislocal, true AS convalidated "
+                                 "true AS conislocal, true AS convalidated, "
+                                 "false as conisonly "
                                  "FROM pg_catalog.pg_constraint "
                                  "WHERE conrelid = '%u'::pg_catalog.oid "
                                  "   AND contype = 'c' "
                appendPQExpBuffer(q, "SELECT tableoid, 0 AS oid, "
                                  "rcname AS conname, "
                                  "'CHECK (' || rcsrc || ')' AS consrc, "
-                                 "true AS conislocal, true AS convalidated "
+                                 "true AS conislocal, true AS convalidated, "
+                                 "false as conisonly "
                                  "FROM pg_relcheck "
                                  "WHERE rcrelid = '%u'::oid "
                                  "ORDER BY rcname",
                appendPQExpBuffer(q, "SELECT tableoid, oid, "
                                  "rcname AS conname, "
                                  "'CHECK (' || rcsrc || ')' AS consrc, "
-                                 "true AS conislocal, true AS convalidated "
+                                 "true AS conislocal, true AS convalidated, "
+                                 "false as conisonly "
                                  "FROM pg_relcheck "
                                  "WHERE rcrelid = '%u'::oid "
                                  "ORDER BY rcname",
                                  "(SELECT oid FROM pg_class WHERE relname = 'pg_relcheck') AS tableoid, "
                                  "oid, rcname AS conname, "
                                  "'CHECK (' || rcsrc || ')' AS consrc, "
-                                 "true AS conislocal, true AS convalidated "
+                                 "true AS conislocal, true AS convalidated, "
+                                 "false as conisonly "
                                  "FROM pg_relcheck "
                                  "WHERE rcrelid = '%u'::oid "
                                  "ORDER BY rcname",
            for (j = 0; j < numConstrs; j++)
            {
                bool    validated = PQgetvalue(res, j, 5)[0] == 't';
+               bool    isonly = PQgetvalue(res, j, 6)[0] == 't';
 
                constrs[j].dobj.objType = DO_CONSTRAINT;
                constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, 0));
                constrs[j].condeferrable = false;
                constrs[j].condeferred = false;
                constrs[j].conislocal = (PQgetvalue(res, j, 4)[0] == 't');
+               constrs[j].conisonly = isonly;
                /*
                 * An unvalidated constraint needs to be dumped separately, so
                 * that potentially-violating existing data is loaded before
-                * the constraint.
+                * the constraint.  An ONLY constraint needs to be dumped
+                * separately too.
                 */
-               constrs[j].separate = !validated;
+               constrs[j].separate = !validated || isonly;
 
                constrs[j].dobj.dump = tbinfo->dobj.dump;
 
                 * Mark the constraint as needing to appear before the table
                 * --- this is so that any other dependencies of the
                 * constraint will be emitted before we try to create the
-                * table.  If the constraint is not validated, it will be
+                * table.  If the constraint is to be dumped separately, it will be
                 * dumped after data is loaded anyway, so don't do it.  (There's
                 * an automatic dependency in the opposite direction anyway, so
                 * don't need to add one manually here.)
                 */
-               if (validated)
+               if (!constrs[j].separate)
                    addObjectDependency(&tbinfo->dobj,
                                        constrs[j].dobj.dumpId);
 
        /* Ignore if not to be dumped separately */
        if (coninfo->separate)
        {
-           /* not ONLY since we want it to propagate to children */
-           appendPQExpBuffer(q, "ALTER TABLE %s\n",
-                             fmtId(tbinfo->dobj.name));
+           /* add ONLY if we do not want it to propagate to children */
+           appendPQExpBuffer(q, "ALTER TABLE %s %s\n",
+                            coninfo->conisonly ? "ONLY" : "", fmtId(tbinfo->dobj.name));
            appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s;\n",
                              fmtId(coninfo->dobj.name),
                              coninfo->condef);
 
    bool        condeferrable;  /* TRUE if constraint is DEFERRABLE */
    bool        condeferred;    /* TRUE if constraint is INITIALLY DEFERRED */
    bool        conislocal;     /* TRUE if constraint has local definition */
+   bool        conisonly;      /* TRUE if constraint is non-inheritable */
    bool        separate;       /* TRUE if must dump as separate item */
 } ConstraintInfo;
 
 
        /* print table (and column) check constraints */
        if (tableinfo.checks)
        {
+           char *is_only;
+
+           if (pset.sversion >= 90200)
+               is_only = "r.conisonly";
+           else
+               is_only = "false AS conisonly";
+
            printfPQExpBuffer(&buf,
-                             "SELECT r.conname, "
+                             "SELECT r.conname, %s, "
                              "pg_catalog.pg_get_constraintdef(r.oid, true)\n"
                              "FROM pg_catalog.pg_constraint r\n"
-                  "WHERE r.conrelid = '%s' AND r.contype = 'c'\nORDER BY 1;",
-                             oid);
+                  "WHERE r.conrelid = '%s' AND r.contype = 'c'\n"
+                             "ORDER BY 2 DESC, 1;",
+                             is_only, oid);
            result = PSQLexec(buf.data, false);
            if (!result)
                goto error_return;
                for (i = 0; i < tuples; i++)
                {
                    /* untranslated contraint name and def */
-                   printfPQExpBuffer(&buf, "    \"%s\" %s",
+                   printfPQExpBuffer(&buf, "    \"%s\"%s%s",
                                      PQgetvalue(result, i, 0),
-                                     PQgetvalue(result, i, 1));
+                                     (strcmp(PQgetvalue(result, i, 1), "t") == 0) ? " (ONLY) ":" ",
+                                     PQgetvalue(result, i, 2));
 
                    printTableAddFooter(&cont, buf.data);
                }
 
    char       *ccname;
    char       *ccbin;          /* nodeToString representation of expr */
    bool        ccvalid;
+   bool        cconly;         /* this is a non-inheritable constraint */
 } ConstrCheck;
 
 /* This structure contains constraints of a tuple */
 
    bool        skip_validation;    /* skip validation? (only for CHECK) */
    bool        is_local;       /* constraint has local (non-inherited) def */
    int         inhcount;       /* number of times constraint is inherited */
+   bool        is_only;        /* constraint has local def and cannot be inherited */
 } CookedConstraint;
 
 extern Relation heap_create(const char *relname,
                          List *newColDefaults,
                          List *newConstraints,
                          bool allow_merge,
-                         bool is_local);
+                         bool is_local,
+                         bool is_only);
 
 extern void StoreAttrDefault(Relation rel, AttrNumber attnum, Node *expr);
 
 
    /* Number of times inherited from direct parent relation(s) */
    int4        coninhcount;
 
+   /* Has a local definition and cannot be inherited */
+   bool        conisonly;
+
    /*
     * VARIABLE LENGTH FIELDS start here.  These fields may be NULL, too.
     */
  *     compiler constants for pg_constraint
  * ----------------
  */
-#define Natts_pg_constraint                    23
+#define Natts_pg_constraint                    24
 #define Anum_pg_constraint_conname         1
 #define Anum_pg_constraint_connamespace        2
 #define Anum_pg_constraint_contype         3
 #define Anum_pg_constraint_confmatchtype   13
 #define Anum_pg_constraint_conislocal      14
 #define Anum_pg_constraint_coninhcount     15
-#define Anum_pg_constraint_conkey          16
-#define Anum_pg_constraint_confkey         17
-#define Anum_pg_constraint_conpfeqop       18
-#define Anum_pg_constraint_conppeqop       19
-#define Anum_pg_constraint_conffeqop       20
-#define Anum_pg_constraint_conexclop       21
-#define Anum_pg_constraint_conbin          22
-#define Anum_pg_constraint_consrc          23
+#define Anum_pg_constraint_conisonly       16
+#define Anum_pg_constraint_conkey          17
+#define Anum_pg_constraint_confkey         18
+#define Anum_pg_constraint_conpfeqop       19
+#define Anum_pg_constraint_conppeqop       20
+#define Anum_pg_constraint_conffeqop       21
+#define Anum_pg_constraint_conexclop       22
+#define Anum_pg_constraint_conbin          23
+#define Anum_pg_constraint_consrc          24
 
 
 /* Valid values for contype */
                      const char *conBin,
                      const char *conSrc,
                      bool conIsLocal,
-                     int conInhCount);
+                     int conInhCount,
+                     bool conIsOnly);
 
 extern void RemoveConstraintById(Oid conId);
 extern void RenameConstraintById(Oid conId, const char *newname);
 
 drop table atacc2 cascade;
 NOTICE:  drop cascades to table atacc3
 drop table atacc1;
--- adding only to a parent is disallowed as of 8.4
+-- adding only to a parent is allowed as of 9.2
 create table atacc1 (test int);
 create table atacc2 (test2 int) inherits (atacc1);
--- fail:
-alter table only atacc1 add constraint foo check (test>0);
-ERROR:  constraint must be added to child tables too
 -- ok:
-alter table only atacc2 add constraint foo check (test>0);
--- check constraint not there on parent
+alter table only atacc1 add constraint foo check (test>0);
+-- check constraint is not there on child
+insert into atacc2 (test) values (-3);
+-- check constraint is there on parent
 insert into atacc1 (test) values (-3);
+ERROR:  new row for relation "atacc1" violates check constraint "foo"
+DETAIL:  Failing row contains (-3).
 insert into atacc1 (test) values (3);
--- check constraint is there on child
-insert into atacc2 (test) values (-3);
-ERROR:  new row for relation "atacc2" violates check constraint "foo"
-DETAIL:  Failing row contains (-3, null).
-insert into atacc2 (test) values (3);
+-- fail, violating row:
+alter table only atacc2 add constraint foo check (test>0);
+ERROR:  check constraint "foo" is violated by some row
 drop table atacc2;
 drop table atacc1;
 -- test unique constraint adding
 
  32 | one | two | three
 (1 row)
 
+-- Test non-inheritable parent constraints
+create table p1(ff1 int);
+alter table only p1 add constraint p1chk check (ff1 > 0);
+alter table p1 add constraint p2chk check (ff1 > 10);
+-- conisonly should be true for ONLY constraint
+select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.conisonly from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname = 'p1';
+ relname | conname | contype | conislocal | coninhcount | conisonly 
+---------+---------+---------+------------+-------------+-----------
+ p1      | p1chk   | c       | t          |           0 | t
+ p1      | p2chk   | c       | t          |           0 | f
+(2 rows)
+
+-- Test that child does not inherit ONLY constraints
+create table c1 () inherits (p1);
+\d p1
+      Table "public.p1"
+ Column |  Type   | Modifiers 
+--------+---------+-----------
+ ff1    | integer | 
+Check constraints:
+    "p1chk" (ONLY) CHECK (ff1 > 0)
+    "p2chk" CHECK (ff1 > 10)
+Number of child tables: 1 (Use \d+ to list them.)
+
+\d c1
+      Table "public.c1"
+ Column |  Type   | Modifiers 
+--------+---------+-----------
+ ff1    | integer | 
+Check constraints:
+    "p2chk" CHECK (ff1 > 10)
+Inherits: p1
+
+drop table p1 cascade;
+NOTICE:  drop cascades to table c1
 -- Tests for casting between the rowtypes of parent and child
 -- tables. See the pgsql-hackers thread beginning Dec. 4/04
 create table base (i integer);
 
 drop table atacc2 cascade;
 drop table atacc1;
 
--- adding only to a parent is disallowed as of 8.4
+-- adding only to a parent is allowed as of 9.2
 
 create table atacc1 (test int);
 create table atacc2 (test2 int) inherits (atacc1);
--- fail:
-alter table only atacc1 add constraint foo check (test>0);
 -- ok:
-alter table only atacc2 add constraint foo check (test>0);
--- check constraint not there on parent
+alter table only atacc1 add constraint foo check (test>0);
+-- check constraint is not there on child
+insert into atacc2 (test) values (-3);
+-- check constraint is there on parent
 insert into atacc1 (test) values (-3);
 insert into atacc1 (test) values (3);
--- check constraint is there on child
-insert into atacc2 (test) values (-3);
-insert into atacc2 (test) values (3);
+-- fail, violating row:
+alter table only atacc2 add constraint foo check (test>0);
 drop table atacc2;
 drop table atacc1;
 
 
 alter table a alter column aa type integer using bit_length(aa);
 select * from d;
 
+-- Test non-inheritable parent constraints
+create table p1(ff1 int);
+alter table only p1 add constraint p1chk check (ff1 > 0);
+alter table p1 add constraint p2chk check (ff1 > 10);
+-- conisonly should be true for ONLY constraint
+select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.conisonly from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname = 'p1';
+
+-- Test that child does not inherit ONLY constraints
+create table c1 () inherits (p1);
+\d p1
+\d c1
+
+drop table p1 cascade;
+
 -- Tests for casting between the rowtypes of parent and child
 -- tables. See the pgsql-hackers thread beginning Dec. 4/04
 create table base (i integer);