Disallow NO INHERIT not-null constraints on partitioned tables
authorAlvaro Herrera <[email protected]>
Thu, 2 May 2024 08:51:46 +0000 (10:51 +0200)
committerAlvaro Herrera <[email protected]>
Thu, 2 May 2024 08:54:12 +0000 (10:54 +0200)
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

src/backend/parser/parse_utilcmd.c
src/bin/pg_dump/pg_dump.c
src/test/regress/expected/constraints.out
src/test/regress/sql/constraints.sql

index fef084f5d525feb8569ef371552ec6a17845fb47..9fb6ff86db55c69b89255be995158bcbec5b1d26 100644 (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;
 
index 242ebe807f5885e8f5ec560238c53b2a7e1ee7a1..379debac24a05c520bb02eb65b6471257e84327b 100644 (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)
index 2fc0be7925b08c0bfcb2686605dc811b47004f3f..ec7c9e53d0208ad5136cbc3af39cde7ee1c18552 100644 (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);
index 8f85e72050f4328750f475b13198225c4789cacd..e753b8c3452d67ba07da5a483ca3cdd2a867a730 100644 (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);