Re: pg17 issues with not-null contraints
Alvaro Herrera <alvherre@alvh.no-ip.org>
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
To: Justin Pryzby <pryzby@telsasoft.com>
Cc: Kyotaro Horiguchi <horikyota.ntt@gmail.com>, pgsql-hackers@lists.postgresql.org
Date: 2024-04-15T16:30:29Z
Lists: pgsql-hackers
On 2024-Apr-15, Alvaro Herrera wrote: > On 2024-Apr-15, Justin Pryzby wrote: > > postgres=# CREATE TABLE iparent(id serial PRIMARY KEY); CREATE TABLE child (id int) INHERITS (iparent); ALTER TABLE child ALTER id DROP NOT NULL; ALTER TABLE child ADD CONSTRAINT p PRIMARY KEY (id); > > > > $ pg_dump -h /tmp -p 5678 postgres -Fc |pg_restore -1 -h /tmp -p 5679 -d postgres > > ERROR: cannot change NO INHERIT status of inherited NOT NULL constraint "pgdump_throwaway_notnull_0" on relation "child" > > STATEMENT: ALTER TABLE ONLY public.iparent > > ADD CONSTRAINT iparent_pkey PRIMARY KEY (id); > Hmm, apparently if the table is "iparent", the primary key is created in > the child first; if the table is "parent", then the PK is created first > there. I think the problem is that the ADD CONSTRAINT for the PK should > not be recursing at all in this case ... seeing in particular that the > command specifies ONLY. Should be a simple fix, looking now. So the problem is that the ADD CONSTRAINT PRIMARY KEY in the parent table wants to recurse to the child, so that a NOT NULL constraint is created on each column. If the child is created first, there's already a NOT NULL NO INHERIT constraint in it which was created for its own primary key, so the internal recursion in the parent's ADD PK fails. A fix doesn't look all that simple: - As I said in my earlier reply, my first thought was to have ALTER TABLE ADD PRIMARY KEY not recurse if the command is ALTER TABLE ONLY. This doesn't work, because the point of that recursion is precisely to handle this case, so if we do that, we break the other stuff that this was added to solve. - Second thought was to add a bespoke dependency in pg_dump.c so that the child PK is dumped after the parent PK. I looked at the code, didn't like the idea of adding such a hack, went looking for other ideas. - Third thought was to hack AdjustNotNullInheritance1() so that it changes the conisnoinherit flag in this particular case. Works great, except that once we mark this constraint as inherited, we cannot drop it; and since it's a constraint marked "throwaway", pg_dump expects to be able to drop it, which means the ALTER TABLE DROP CONSTRAINT throws an error, and a constraint named pgdump_throwaway_notnull_0 remains in place. - Fourth thought: we do as in the third thought, except we also allow DROP CONSTRAINT a constraint that's marked "local, inherited" to be simply an inherited constraint (remove its "local" marker). I'm going to try to implement this fourth idea, which seems promising. I think if we do that, the end result will be identical to the case where the child is created after the parent. However, we'll also need that constraint to have a name better than pgdump_throwaway_notnull_NN. -- Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Fix inconsistencies in error messages
- 21ac38f498b3 17.0 landed
-
Fix restore of not-null constraints with inheritance
- d9f686a72ee9 17.0 landed
-
Fix propagating attnotnull in multiple inheritance
- c3709100be73 17.0 cited
-
Doc: mention CREATE+ATTACH PARTITION with CREATE TABLE...PARTITION OF.
- f170b572d2b4 16.0 cited
-
Allow ATTACH PARTITION with only ShareUpdateExclusiveLock.
- 898e5e3290a7 12.0 cited