Disallow NO INHERIT not-null constraints on partitioned tables

Such constraints are semantically useless and only bring weird cases
along, so reject them.

As a side effect, we can no longer have "throwaway" constraints in
pg_dump for primary keys in partitioned tables, but since they don't
serve any useful purpose, we can just omit them.

Maybe this should be done for all types of constraints, but it's just
not-null ones that acquired this "ability" in the 17 timeframe, so for
the moment I'm not changing anything else.

Per note by Alexander Lakhin.
Discussion: https://postgr.es/m/7d923a66-55f0-3395-cd40-81c142b5448b@gmail.com
This commit is contained in:
Alvaro Herrera 2024-05-02 10:51:46 +02:00
parent a27ccc235d
commit 13daa33fa5
No known key found for this signature in database
GPG Key ID: 1C20ACB9D5C564AE
4 changed files with 33 additions and 2 deletions

View File

@ -679,6 +679,10 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
break;
case CONSTR_NOTNULL:
if (cxt->ispartitioned && constraint->is_no_inherit)
ereport(ERROR,
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("not-null constraints on partitioned tables cannot be NO INHERIT"));
/*
* Disallow conflicting [NOT] NULL markings
@ -969,6 +973,12 @@ transformTableConstraint(CreateStmtContext *cxt, Constraint *constraint)
break;
case CONSTR_NOTNULL:
if (cxt->ispartitioned && constraint->is_no_inherit)
ereport(ERROR,
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("not-null constraints on partitioned tables cannot be NO INHERIT"));
cxt->nnconstraints = lappend(cxt->nnconstraints, constraint);
break;

View File

@ -9052,7 +9052,15 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
tbinfo->attnames[j]);
}
else if (PQgetvalue(res, r, i_notnull_is_pk)[0] == 't')
use_throwaway_notnull = true;
{
/*
* We want this flag to be set for columns of a primary
* key in which data is going to be loaded by the dump we
* produce; thus a partitioned table doesn't need it.
*/
if (tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
use_throwaway_notnull = true;
}
else if (!PQgetisnull(res, r, i_notnull_name))
use_unnamed_notnull = true;
}
@ -9092,7 +9100,11 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
}
}
else if (PQgetvalue(res, r, i_notnull_is_pk)[0] == 't')
use_throwaway_notnull = true;
{
/* see above */
if (tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
use_throwaway_notnull = true;
}
}
if (use_unnamed_notnull)

View File

@ -321,6 +321,11 @@ ALTER TABLE ATACC1 ADD NOT NULL a NO INHERIT;
Inherits: atacc1
DROP TABLE ATACC1, ATACC2;
-- no can do
CREATE TABLE ATACC1 (a int NOT NULL NO INHERIT) PARTITION BY LIST (a);
ERROR: not-null constraints on partitioned tables cannot be NO INHERIT
CREATE TABLE ATACC1 (a int, NOT NULL a NO INHERIT) PARTITION BY LIST (a);
ERROR: not-null constraints on partitioned tables cannot be NO INHERIT
-- overridding a no-inherit constraint with an inheritable one
CREATE TABLE ATACC2 (a int, CONSTRAINT a_is_not_null NOT NULL a NO INHERIT);
CREATE TABLE ATACC1 (a int);

View File

@ -212,6 +212,10 @@ ALTER TABLE ATACC1 ADD NOT NULL a NO INHERIT;
\d+ ATACC2
DROP TABLE ATACC1, ATACC2;
-- no can do
CREATE TABLE ATACC1 (a int NOT NULL NO INHERIT) PARTITION BY LIST (a);
CREATE TABLE ATACC1 (a int, NOT NULL a NO INHERIT) PARTITION BY LIST (a);
-- overridding a no-inherit constraint with an inheritable one
CREATE TABLE ATACC2 (a int, CONSTRAINT a_is_not_null NOT NULL a NO INHERIT);
CREATE TABLE ATACC1 (a int);