Skip to content

Commit

Permalink
Clean up MergeCheckConstraint()
Browse files Browse the repository at this point in the history
If the constraint is not already in the list, add it ourselves,
instead of making the caller do it.  This makes the interface more
consistent with other "merge" functions in this file.

Discussion: https://www.postgresql.org/message-id/flat/52a125e4-ff9a-95f5-9f61-b87cf447e4da%40eisentraut.org
  • Loading branch information
petere committed Sep 26, 2023
1 parent 28d3c2d commit 369202b
Showing 1 changed file with 22 additions and 26 deletions.
48 changes: 22 additions & 26 deletions src/backend/commands/tablecmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ static void RangeVarCallbackForTruncate(const RangeVar *relation,
static List *MergeAttributes(List *schema, List *supers, char relpersistence,
bool is_partition, List **supconstr,
List **supnotnulls);
static bool MergeCheckConstraint(List *constraints, char *name, Node *expr);
static List *MergeCheckConstraint(List *constraints, const char *name, Node *expr);
static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel);
static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
static void StoreCatalogInheritance(Oid relationId, List *supers,
Expand Down Expand Up @@ -2913,24 +2913,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
name,
RelationGetRelationName(relation))));

/* check for duplicate */
if (!MergeCheckConstraint(constraints, name, expr))
{
/* nope, this is a new one */
CookedConstraint *cooked;

cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
cooked->contype = CONSTR_CHECK;
cooked->conoid = InvalidOid; /* until created */
cooked->name = pstrdup(name);
cooked->attnum = 0; /* not used for constraints */
cooked->expr = expr;
cooked->skip_validation = false;
cooked->is_local = false;
cooked->inhcount = 1;
cooked->is_no_inherit = false;
constraints = lappend(constraints, cooked);
}
constraints = MergeCheckConstraint(constraints, name, expr);
}
}

Expand Down Expand Up @@ -3277,13 +3260,17 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
*
* constraints is a list of CookedConstraint structs for previous constraints.
*
* Returns true if merged (constraint is a duplicate), or false if it's
* got a so-far-unique name, or throws error if conflict.
* If the new constraint matches an existing one, then the existing
* constraint's inheritance count is updated. If there is a conflict (same
* name but different expression), throw an error. If the constraint neither
* matches nor conflicts with an existing one, a new constraint is appended to
* the list.
*/
static bool
MergeCheckConstraint(List *constraints, char *name, Node *expr)
static List *
MergeCheckConstraint(List *constraints, const char *name, Node *expr)
{
ListCell *lc;
CookedConstraint *newcon;

foreach(lc, constraints)
{
Expand All @@ -3297,13 +3284,13 @@ MergeCheckConstraint(List *constraints, char *name, Node *expr)

if (equal(expr, ccon->expr))
{
/* OK to merge */
/* OK to merge constraint with existing */
ccon->inhcount++;
if (ccon->inhcount < 0)
ereport(ERROR,
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("too many inheritance parents"));
return true;
return constraints;
}

ereport(ERROR,
Expand All @@ -3312,7 +3299,16 @@ MergeCheckConstraint(List *constraints, char *name, Node *expr)
name)));
}

return false;
/*
* Constraint couldn't be merged with an existing one and also didn't
* conflict with an existing one, so add it as a new one to the list.
*/
newcon = palloc0_object(CookedConstraint);
newcon->contype = CONSTR_CHECK;
newcon->name = pstrdup(name);
newcon->expr = expr;
newcon->inhcount = 1;
return lappend(constraints, newcon);
}


Expand Down

0 comments on commit 369202b

Please sign in to comment.