mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Fix not-null constraint test
When a partitioned table has a primary key, trying to find the corresponding not-null constraint for that column would come up empty, causing code that's trying to check said not-null constraint to crash. Fix by only running the check when the not-null constraint exists. Reported-by: Alexander Lakhin <exclusion@gmail.com> Discussion: https://postgr.es/m/d57b4a69-7394-3146-5976-9a1ef27e7972@gmail.com
This commit is contained in:
parent
e09d763e25
commit
d0ec2ddbe0
@ -15746,9 +15746,10 @@ MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel)
|
||||
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)
|
||||
{
|
||||
@ -15756,11 +15757,12 @@ MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel)
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -15981,10 +15983,20 @@ MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel)
|
||||
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);
|
||||
|
@ -1006,6 +1006,17 @@ Inherits: cnn_grandchild,
|
||||
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;
|
||||
|
@ -657,6 +657,17 @@ ALTER TABLE cnn_parent ADD PRIMARY KEY USING INDEX b_uq;
|
||||
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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user