Re: cataloguing NOT NULL constraints

Alvaro Herrera <alvherre@alvh.no-ip.org>

From: Alvaro Herrera <alvherre@alvh.no-ip.org>
To: Dean Rasheed <dean.a.rasheed@gmail.com>
Cc: Robert Haas <robertmhaas@gmail.com>, Peter Eisentraut <peter@eisentraut.org>, pgsql-hackers@lists.postgresql.org
Date: 2023-07-28T10:47:44Z
Lists: pgsql-hackers

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Revert structural changes to not-null constraints

  2. Fix inconsistencies in error messages

  3. Disallow direct change of NO INHERIT of not-null constraints

  4. Disallow NO INHERIT not-null constraints on partitioned tables

  5. Better handle indirect constraint drops

  6. Don't try to assign smart names to constraints

  7. Fix restore of not-null constraints with inheritance

  8. ATTACH PARTITION: Don't match a PK with a UNIQUE constraint

  9. Fix propagating attnotnull in multiple inheritance

  10. Check stack depth in new recursive functions

  11. Move privilege check to the right place

  12. Update information_schema definition for not-null constraints

  13. Fix not-null constraint test

  14. Disallow changing NO INHERIT status of a not-null constraint

  15. Catalog not-null constraints

  16. parallel_schedule: add comment on event_trigger test dependency

  17. Revert "Catalog NOT NULL constraints" and fallout

  18. Adjust contrib/sepgsql regression test expected outputs.

  19. Fix table name clash in recently introduced test

  20. Catalog NOT NULL constraints

  21. Change the rules for inherited CHECK constraints to be essentially the same

> > Given the following sequence:
> > 
> > drop table if exists p,c;
> > create table p(a int primary key);
> > create table c() inherits (p);
> > alter table p drop constraint p_pkey;

> > However, c.a remains non-nullable, with a NOT NULL constraint that
> > claims to be inherited:
> > 
> > \d+ c
> >                                             Table "public.c"
> >  Column |  Type   | Collation | Nullable | Default | Storage |
> > Compression | Stats target | Description
> > --------+---------+-----------+----------+---------+---------+-------------+--------------+-------------
> >  a      | integer |           | not null |         | plain   |
> >     |              |
> > Not null constraints:
> >     "c_a_not_null" NOT NULL "a" (inherited)
> > Inherits: p
> > Access method: heap
> > 
> > That's a problem, because now the NOT NULL constraint on c cannot be
> > dropped (attempting to drop it on c errors out because it thinks it's
> > inherited, but it can't be dropped via p, because p.a is already
> > nullable).

So I implemented a fix for this (namely: fix the inhcount to be 0
initially), and it works well, but it does cause a definitional problem:
any time we create a child table that inherits from another table that
has a primary key, all the columns in the child table will get normal,
visible, droppable NOT NULL constraints.  Thus, pg_dump for example will
output that constraint exactly as if the user had specified it in the
child's CREATE TABLE command.  By itself this doesn't bother me, though
I admit it seems a little odd.

When you restore such a setup from pg_dump, things work perfectly -- I
mean, you don't get a second constraint.  But if you do drop the
constraint, then it will be reinstated by the next pg_dump as if you
hadn't dropped it, by way of it springing to life from the PK.

To avoid that, one option would be to make this NN constraint
undroppable ...  but I don't see how.  One option might be to add a
pg_depend row that links the NOT NULL constraint to its PK constraint.
But this will be a strange case that occurs nowhere else, since other
NOT NULL constraint don't have such pg_depend rows.  Also, I won't know
how pg_dump likes this until I implement it.

-- 
Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/