@@ -353,7 +353,7 @@ static void RangeVarCallbackForTruncate(const RangeVar *relation,
353
353
static List *MergeAttributes(List *schema, List *supers, char relpersistence,
354
354
bool is_partition, List **supconstr,
355
355
List **supnotnulls);
356
- static bool MergeCheckConstraint(List *constraints, char *name, Node *expr);
356
+ static List * MergeCheckConstraint(List *constraints, const char *name, Node *expr);
357
357
static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel);
358
358
static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
359
359
static void StoreCatalogInheritance(Oid relationId, List *supers,
@@ -2913,24 +2913,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
2913
2913
name,
2914
2914
RelationGetRelationName(relation))));
2915
2915
2916
- /* check for duplicate */
2917
- if (!MergeCheckConstraint(constraints, name, expr))
2918
- {
2919
- /* nope, this is a new one */
2920
- CookedConstraint *cooked;
2921
-
2922
- cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
2923
- cooked->contype = CONSTR_CHECK;
2924
- cooked->conoid = InvalidOid; /* until created */
2925
- cooked->name = pstrdup(name);
2926
- cooked->attnum = 0; /* not used for constraints */
2927
- cooked->expr = expr;
2928
- cooked->skip_validation = false;
2929
- cooked->is_local = false;
2930
- cooked->inhcount = 1;
2931
- cooked->is_no_inherit = false;
2932
- constraints = lappend(constraints, cooked);
2933
- }
2916
+ constraints = MergeCheckConstraint(constraints, name, expr);
2934
2917
}
2935
2918
}
2936
2919
@@ -3277,13 +3260,17 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
3277
3260
*
3278
3261
* constraints is a list of CookedConstraint structs for previous constraints.
3279
3262
*
3280
- * Returns true if merged (constraint is a duplicate), or false if it's
3281
- * got a so-far-unique name, or throws error if conflict.
3263
+ * If the new constraint matches an existing one, then the existing
3264
+ * constraint's inheritance count is updated. If there is a conflict (same
3265
+ * name but different expression), throw an error. If the constraint neither
3266
+ * matches nor conflicts with an existing one, a new constraint is appended to
3267
+ * the list.
3282
3268
*/
3283
- static bool
3284
- MergeCheckConstraint(List *constraints, char *name, Node *expr)
3269
+ static List *
3270
+ MergeCheckConstraint(List *constraints, const char *name, Node *expr)
3285
3271
{
3286
3272
ListCell *lc;
3273
+ CookedConstraint *newcon;
3287
3274
3288
3275
foreach(lc, constraints)
3289
3276
{
@@ -3297,13 +3284,13 @@ MergeCheckConstraint(List *constraints, char *name, Node *expr)
3297
3284
3298
3285
if (equal(expr, ccon->expr))
3299
3286
{
3300
- /* OK to merge */
3287
+ /* OK to merge constraint with existing */
3301
3288
ccon->inhcount++;
3302
3289
if (ccon->inhcount < 0)
3303
3290
ereport(ERROR,
3304
3291
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3305
3292
errmsg("too many inheritance parents"));
3306
- return true ;
3293
+ return constraints ;
3307
3294
}
3308
3295
3309
3296
ereport(ERROR,
@@ -3312,7 +3299,16 @@ MergeCheckConstraint(List *constraints, char *name, Node *expr)
3312
3299
name)));
3313
3300
}
3314
3301
3315
- return false;
3302
+ /*
3303
+ * Constraint couldn't be merged with an existing one and also didn't
3304
+ * conflict with an existing one, so add it as a new one to the list.
3305
+ */
3306
+ newcon = palloc0_object(CookedConstraint);
3307
+ newcon->contype = CONSTR_CHECK;
3308
+ newcon->name = pstrdup(name);
3309
+ newcon->expr = expr;
3310
+ newcon->inhcount = 1;
3311
+ return lappend(constraints, newcon);
3316
3312
}
3317
3313
3318
3314
0 commit comments