@@ -579,6 +579,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
579579 cooked -> skip_validation = false;
580580 cooked -> is_local = true; /* not used for defaults */
581581 cooked -> inhcount = 0 ; /* ditto */
582+ cooked -> is_only = false;
582583 cookedDefaults = lappend (cookedDefaults , cooked );
583584 descriptor -> attrs [attnum - 1 ]-> atthasdef = true;
584585 }
@@ -638,7 +639,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
638639 */
639640 if (rawDefaults || stmt -> constraints )
640641 AddRelationNewConstraints (rel , rawDefaults , stmt -> constraints ,
641- true, true);
642+ true, true, false );
642643
643644 /*
644645 * Clean up. We keep lock on new relation (although it shouldn't be
@@ -1599,6 +1600,10 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
15991600 char * name = check [i ].ccname ;
16001601 Node * expr ;
16011602
1603+ /* ignore if the constraint is non-inheritable */
1604+ if (check [i ].cconly )
1605+ continue ;
1606+
16021607 /* adjust varattnos of ccbin here */
16031608 expr = stringToNode (check [i ].ccbin );
16041609 change_varattnos_of_a_node (expr , newattno );
@@ -1617,6 +1622,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
16171622 cooked -> skip_validation = false;
16181623 cooked -> is_local = false;
16191624 cooked -> inhcount = 1 ;
1625+ cooked -> is_only = false;
16201626 constraints = lappend (constraints , cooked );
16211627 }
16221628 }
@@ -4501,7 +4507,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
45014507 * This function is intended for CREATE TABLE, so it processes a
45024508 * _list_ of defaults, but we just do one.
45034509 */
4504- AddRelationNewConstraints (rel , list_make1 (rawEnt ), NIL , false, true);
4510+ AddRelationNewConstraints (rel , list_make1 (rawEnt ), NIL , false, true, false );
45054511
45064512 /* Make the additional catalog changes visible */
45074513 CommandCounterIncrement ();
@@ -4898,7 +4904,7 @@ ATExecColumnDefault(Relation rel, const char *colName,
48984904 * This function is intended for CREATE TABLE, so it processes a
48994905 * _list_ of defaults, but we just do one.
49004906 */
4901- AddRelationNewConstraints (rel , list_make1 (rawEnt ), NIL , false, true);
4907+ AddRelationNewConstraints (rel , list_make1 (rawEnt ), NIL , false, true, false );
49024908 }
49034909}
49044910
@@ -5562,10 +5568,16 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
55625568 * omitted from the returned list, which is what we want: we do not need
55635569 * to do any validation work. That can only happen at child tables,
55645570 * though, since we disallow merging at the top level.
5571+ *
5572+ * Note: we set is_only based on the recurse flag which is false when
5573+ * interpretInhOption() of our statement returns false all the way up
5574+ * in AlterTable and gets passed all the way down to here.
55655575 */
55665576 newcons = AddRelationNewConstraints (rel , NIL ,
55675577 list_make1 (copyObject (constr )),
5568- recursing , !recursing );
5578+ recursing , /* allow_merge */
5579+ !recursing , /* is_local */
5580+ !recurse && !recursing ); /* is_only */
55695581
55705582 /* Add each to-be-validated constraint to Phase 3's queue */
55715583 foreach (lcon , newcons )
@@ -5605,22 +5617,19 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
56055617 if (newcons == NIL )
56065618 return ;
56075619
5620+ /*
5621+ * Adding an ONLY constraint? No need to find our children
5622+ */
5623+ if (!recurse && !recursing )
5624+ return ;
5625+
56085626 /*
56095627 * Propagate to children as appropriate. Unlike most other ALTER
56105628 * routines, we have to do this one level of recursion at a time; we can't
56115629 * use find_all_inheritors to do it in one pass.
56125630 */
56135631 children = find_inheritance_children (RelationGetRelid (rel ), lockmode );
56145632
5615- /*
5616- * If we are told not to recurse, there had better not be any child
5617- * tables; else the addition would put them out of step.
5618- */
5619- if (children && !recurse )
5620- ereport (ERROR ,
5621- (errcode (ERRCODE_INVALID_TABLE_DEFINITION ),
5622- errmsg ("constraint must be added to child tables too" )));
5623-
56245633 foreach (child , children )
56255634 {
56265635 Oid childrelid = lfirst_oid (child );
@@ -5914,7 +5923,8 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
59145923 NULL ,
59155924 NULL ,
59165925 true, /* islocal */
5917- 0 ); /* inhcount */
5926+ 0 , /* inhcount */
5927+ false); /* isonly */
59185928
59195929 /*
59205930 * Create the triggers that will enforce the constraint.
@@ -6755,6 +6765,7 @@ ATExecDropConstraint(Relation rel, const char *constrName,
67556765 HeapTuple tuple ;
67566766 bool found = false;
67576767 bool is_check_constraint = false;
6768+ bool is_only_constraint = false;
67586769
67596770 /* At top level, permission check was done in ATPrepCmd, else do it */
67606771 if (recursing )
@@ -6791,6 +6802,12 @@ ATExecDropConstraint(Relation rel, const char *constrName,
67916802 /* Right now only CHECK constraints can be inherited */
67926803 if (con -> contype == CONSTRAINT_CHECK )
67936804 is_check_constraint = true;
6805+
6806+ if (con -> conisonly )
6807+ {
6808+ Assert (is_check_constraint );
6809+ is_only_constraint = true;
6810+ }
67946811
67956812 /*
67966813 * Perform the actual constraint deletion
@@ -6802,6 +6819,9 @@ ATExecDropConstraint(Relation rel, const char *constrName,
68026819 performDeletion (& conobj , behavior );
68036820
68046821 found = true;
6822+
6823+ /* constraint found and dropped -- no need to keep looping */
6824+ break ;
68056825 }
68066826
68076827 systable_endscan (scan );
@@ -6830,7 +6850,7 @@ ATExecDropConstraint(Relation rel, const char *constrName,
68306850 * routines, we have to do this one level of recursion at a time; we can't
68316851 * use find_all_inheritors to do it in one pass.
68326852 */
6833- if (is_check_constraint )
6853+ if (is_check_constraint && ! is_only_constraint )
68346854 children = find_inheritance_children (RelationGetRelid (rel ), lockmode );
68356855 else
68366856 children = NIL ;
0 commit comments