MergeConstraintsIntoExisting.no-cfbot
application/octet-stream
Filename: MergeConstraintsIntoExisting.no-cfbot
Type: application/octet-stream
Part: 0
Message:
Re: not null constraints, again
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 050aad0d6a..ee1edd7187 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -16280,42 +16280,59 @@ MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel)
if (strcmp(NameStr(parent_con->conname),
NameStr(child_con->conname)) != 0)
continue;
+
+ if(!constraints_equivalent(parent_tuple, child_tuple, RelationGetDescr(constraintrel)))
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("child table \"%s\" has different definition for check constraint \"%s\"",
+ RelationGetRelationName(child_rel), NameStr(parent_con->conname))));
+ /*
+ * If the CHECK child constraint is "no inherit" then cannot
+ * merge.
+ *
+ * This is not desirable for not-null constraints, mostly because
+ * it breaks our pg_upgrade strategy, but it also makes sense on
+ * its own: if a child has its own not-null constraint and then
+ * acquires a parent with the same constraint, then we start to
+ * enforce that constraint for all the descendants of that child
+ * too, if any.
+ */
+ if (child_con->connoinherit)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"",
+ NameStr(child_con->conname), RelationGetRelationName(child_rel))));
}
else if (child_con->contype == CONSTRAINT_NOTNULL)
{
AttrNumber parent_attno = extractNotNullColumn(parent_tuple);
AttrNumber child_attno = extractNotNullColumn(child_tuple);
- if (strcmp(get_attname(parent_relid, parent_attno, false),
- get_attname(RelationGetRelid(child_rel), child_attno,
- false)) != 0)
+ Form_pg_attribute part_attr = TupleDescAttr(parent_rel->rd_att, parent_attno - 1);
+ Form_pg_attribute child_attr = TupleDescAttr(child_rel->rd_att, child_attno - 1);
+
+ if (part_attr->attisdropped || child_attr->attisdropped)
continue;
- }
- if (child_con->contype == CONSTRAINT_CHECK &&
- !constraints_equivalent(parent_tuple, child_tuple, RelationGetDescr(constraintrel)))
- ereport(ERROR,
- (errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("child table \"%s\" has different definition for check constraint \"%s\"",
- RelationGetRelationName(child_rel), NameStr(parent_con->conname))));
+ if(strcmp((NameStr(part_attr->attname)), (NameStr(child_attr->attname))) != 0)
+ continue;
- /*
- * If the CHECK child constraint is "no inherit" then cannot
- * merge.
- *
- * This is not desirable for not-null constraints, mostly because
- * it breaks our pg_upgrade strategy, but it also makes sense on
- * its own: if a child has its own not-null constraint and then
- * acquires a parent with the same constraint, then we start to
- * enforce that constraint for all the descendants of that child
- * too, if any.
- */
- if (child_con->contype == CONSTRAINT_CHECK &&
- child_con->connoinherit)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"",
- NameStr(child_con->conname), RelationGetRelationName(child_rel))));
+ /*
+ * If the child has children, it's not possible to turn a NO
+ * INHERIT constraint into an inheritable one: we would need
+ * to recurse to create constraints in those children, but
+ * this is not a good place to do that.
+ */
+ if (child_con->connoinherit && child_rel->rd_rel->relhassubclass)
+ ereport(ERROR,
+ errmsg("cannot add NOT NULL constraint to column \"%s\" of relation \"%s\" with inheritance children",
+ get_attname(RelationGetRelid(child_rel),
+ extractNotNullColumn(child_tuple),
+ false),
+ RelationGetRelationName(child_rel)),
+ errdetail("Existing constraint \"%s\" is marked NO INHERIT.",
+ NameStr(child_con->conname)));
+ }
/*
* If the child constraint is "not valid" then cannot merge with a
@@ -16342,25 +16359,7 @@ MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel)
/* Also reset connoinherit for not-null, if the child has that */
if (child_con->contype == CONSTRAINT_NOTNULL &&
child_con->connoinherit)
- {
- /*
- * If the child has children, it's not possible to turn a NO
- * INHERIT constraint into an inheritable one: we would need
- * to recurse to create constraints in those children, but
- * this is not a good place to do that.
- */
- if (child_rel->rd_rel->relhassubclass)
- ereport(ERROR,
- errmsg("cannot add NOT NULL constraint to column \"%s\" of relation \"%s\" with inheritance children",
- get_attname(RelationGetRelid(child_rel),
- extractNotNullColumn(child_tuple),
- false),
- RelationGetRelationName(child_rel)),
- errdetail("Existing constraint \"%s\" is marked NO INHERIT.",
- NameStr(child_con->conname)));
-
child_con->connoinherit = false;
- }
/*
* In case of partitions, an inherited constraint must be