mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-28 11:55:03 +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:
		| @@ -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. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user