@@ -579,6 +579,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
579
579
cooked -> skip_validation = false;
580
580
cooked -> is_local = true; /* not used for defaults */
581
581
cooked -> inhcount = 0 ; /* ditto */
582
+ cooked -> is_only = false;
582
583
cookedDefaults = lappend (cookedDefaults , cooked );
583
584
descriptor -> attrs [attnum - 1 ]-> atthasdef = true;
584
585
}
@@ -638,7 +639,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
638
639
*/
639
640
if (rawDefaults || stmt -> constraints )
640
641
AddRelationNewConstraints (rel , rawDefaults , stmt -> constraints ,
641
- true, true);
642
+ true, true, false );
642
643
643
644
/*
644
645
* Clean up. We keep lock on new relation (although it shouldn't be
@@ -1599,6 +1600,10 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
1599
1600
char * name = check [i ].ccname ;
1600
1601
Node * expr ;
1601
1602
1603
+ /* ignore if the constraint is non-inheritable */
1604
+ if (check [i ].cconly )
1605
+ continue ;
1606
+
1602
1607
/* adjust varattnos of ccbin here */
1603
1608
expr = stringToNode (check [i ].ccbin );
1604
1609
change_varattnos_of_a_node (expr , newattno );
@@ -1617,6 +1622,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
1617
1622
cooked -> skip_validation = false;
1618
1623
cooked -> is_local = false;
1619
1624
cooked -> inhcount = 1 ;
1625
+ cooked -> is_only = false;
1620
1626
constraints = lappend (constraints , cooked );
1621
1627
}
1622
1628
}
@@ -4501,7 +4507,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
4501
4507
* This function is intended for CREATE TABLE, so it processes a
4502
4508
* _list_ of defaults, but we just do one.
4503
4509
*/
4504
- AddRelationNewConstraints (rel , list_make1 (rawEnt ), NIL , false, true);
4510
+ AddRelationNewConstraints (rel , list_make1 (rawEnt ), NIL , false, true, false );
4505
4511
4506
4512
/* Make the additional catalog changes visible */
4507
4513
CommandCounterIncrement ();
@@ -4898,7 +4904,7 @@ ATExecColumnDefault(Relation rel, const char *colName,
4898
4904
* This function is intended for CREATE TABLE, so it processes a
4899
4905
* _list_ of defaults, but we just do one.
4900
4906
*/
4901
- AddRelationNewConstraints (rel , list_make1 (rawEnt ), NIL , false, true);
4907
+ AddRelationNewConstraints (rel , list_make1 (rawEnt ), NIL , false, true, false );
4902
4908
}
4903
4909
}
4904
4910
@@ -5562,10 +5568,16 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
5562
5568
* omitted from the returned list, which is what we want: we do not need
5563
5569
* to do any validation work. That can only happen at child tables,
5564
5570
* 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.
5565
5575
*/
5566
5576
newcons = AddRelationNewConstraints (rel , NIL ,
5567
5577
list_make1 (copyObject (constr )),
5568
- recursing , !recursing );
5578
+ recursing , /* allow_merge */
5579
+ !recursing , /* is_local */
5580
+ !recurse && !recursing ); /* is_only */
5569
5581
5570
5582
/* Add each to-be-validated constraint to Phase 3's queue */
5571
5583
foreach (lcon , newcons )
@@ -5605,22 +5617,19 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
5605
5617
if (newcons == NIL )
5606
5618
return ;
5607
5619
5620
+ /*
5621
+ * Adding an ONLY constraint? No need to find our children
5622
+ */
5623
+ if (!recurse && !recursing )
5624
+ return ;
5625
+
5608
5626
/*
5609
5627
* Propagate to children as appropriate. Unlike most other ALTER
5610
5628
* routines, we have to do this one level of recursion at a time; we can't
5611
5629
* use find_all_inheritors to do it in one pass.
5612
5630
*/
5613
5631
children = find_inheritance_children (RelationGetRelid (rel ), lockmode );
5614
5632
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
-
5624
5633
foreach (child , children )
5625
5634
{
5626
5635
Oid childrelid = lfirst_oid (child );
@@ -5914,7 +5923,8 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
5914
5923
NULL ,
5915
5924
NULL ,
5916
5925
true, /* islocal */
5917
- 0 ); /* inhcount */
5926
+ 0 , /* inhcount */
5927
+ false); /* isonly */
5918
5928
5919
5929
/*
5920
5930
* Create the triggers that will enforce the constraint.
@@ -6755,6 +6765,7 @@ ATExecDropConstraint(Relation rel, const char *constrName,
6755
6765
HeapTuple tuple ;
6756
6766
bool found = false;
6757
6767
bool is_check_constraint = false;
6768
+ bool is_only_constraint = false;
6758
6769
6759
6770
/* At top level, permission check was done in ATPrepCmd, else do it */
6760
6771
if (recursing )
@@ -6791,6 +6802,12 @@ ATExecDropConstraint(Relation rel, const char *constrName,
6791
6802
/* Right now only CHECK constraints can be inherited */
6792
6803
if (con -> contype == CONSTRAINT_CHECK )
6793
6804
is_check_constraint = true;
6805
+
6806
+ if (con -> conisonly )
6807
+ {
6808
+ Assert (is_check_constraint );
6809
+ is_only_constraint = true;
6810
+ }
6794
6811
6795
6812
/*
6796
6813
* Perform the actual constraint deletion
@@ -6802,6 +6819,9 @@ ATExecDropConstraint(Relation rel, const char *constrName,
6802
6819
performDeletion (& conobj , behavior );
6803
6820
6804
6821
found = true;
6822
+
6823
+ /* constraint found and dropped -- no need to keep looping */
6824
+ break ;
6805
6825
}
6806
6826
6807
6827
systable_endscan (scan );
@@ -6830,7 +6850,7 @@ ATExecDropConstraint(Relation rel, const char *constrName,
6830
6850
* routines, we have to do this one level of recursion at a time; we can't
6831
6851
* use find_all_inheritors to do it in one pass.
6832
6852
*/
6833
- if (is_check_constraint )
6853
+ if (is_check_constraint && ! is_only_constraint )
6834
6854
children = find_inheritance_children (RelationGetRelid (rel ), lockmode );
6835
6855
else
6836
6856
children = NIL ;
0 commit comments