attributeName)));
/*
- * Check child doesn't discard NOT NULL property. (Other
- * constraints are checked elsewhere.) However, if the constraint
- * is NO INHERIT in the parent, this is allowed.
+ * If the parent has a not-null constraint that's not NO INHERIT,
+ * make sure the child has one too.
+ *
+ * Other constraints are checked elsewhere.
*/
if (attribute->attnotnull && !childatt->attnotnull)
{
contup = findNotNullConstraintAttnum(RelationGetRelid(parent_rel),
attribute->attnum);
- if (!((Form_pg_constraint) GETSTRUCT(contup))->connoinherit)
+ if (HeapTupleIsValid(contup) &&
+ !((Form_pg_constraint) GETSTRUCT(contup))->connoinherit)
ereport(ERROR,
- (errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("column \"%s\" in child table must be marked NOT NULL",
- attributeName)));
+ errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("column \"%s\" in child table must be marked NOT NULL",
+ attributeName));
}
/*
systable_endscan(child_scan);
if (!found)
+ {
+ if (parent_con->contype == CONSTRAINT_NOTNULL)
+ ereport(ERROR,
+ errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("column \"%s\" in child table must be marked NOT NULL",
+ get_attname(parent_relid,
+ extractNotNullColumn(parent_tuple),
+ false)));
+
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("child table is missing constraint \"%s\"",
NameStr(parent_con->conname))));
+ }
}
systable_endscan(parent_scan);
ALTER TABLE cnn_parent DROP CONSTRAINT cnn_parent_pkey;
ERROR: constraint "cnn_parent_pkey" of relation "cnn_parent" does not exist
-- keeps these tables around, for pg_upgrade testing
+-- ensure columns in partitions are marked not-null
+create table cnn2_parted(a int primary key) partition by list (a);
+create table cnn2_part1(a int);
+alter table cnn2_parted attach partition cnn2_part1 for values in (1);
+ERROR: primary key column "a" is not marked NOT NULL
+drop table cnn2_parted, cnn2_part1;
+create table cnn2_parted(a int not null) partition by list (a);
+create table cnn2_part1(a int primary key);
+alter table cnn2_parted attach partition cnn2_part1 for values in (1);
+ERROR: column "a" in child table must be marked NOT NULL
+drop table cnn2_parted, cnn2_part1;
-- Comments
-- Setup a low-level role to enforce non-superuser checks.
CREATE ROLE regress_constraint_comments;
ALTER TABLE cnn_parent DROP CONSTRAINT cnn_parent_pkey;
-- keeps these tables around, for pg_upgrade testing
+-- ensure columns in partitions are marked not-null
+create table cnn2_parted(a int primary key) partition by list (a);
+create table cnn2_part1(a int);
+alter table cnn2_parted attach partition cnn2_part1 for values in (1);
+drop table cnn2_parted, cnn2_part1;
+
+create table cnn2_parted(a int not null) partition by list (a);
+create table cnn2_part1(a int primary key);
+alter table cnn2_parted attach partition cnn2_part1 for values in (1);
+drop table cnn2_parted, cnn2_part1;
+
-- Comments
-- Setup a low-level role to enforce non-superuser checks.