Re: Can't find not null constraint, but \d+ shows that

From: Tender Wang <tndrwang(at)gmail(dot)com>
To: Alvaro Herrera <alvherre(at)alvh(dot)no-ip(dot)org>
Cc: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: Can't find not null constraint, but \d+ shows that
Date: 2024-03-27 03:33:29
Message-ID: CAHewXNm8G_GVxb5r+Ed=8N-cMr+V3xd8UbLdk8Sj_yzNTxX6Tw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Alvaro Herrera <alvherre(at)alvh(dot)no-ip(dot)org> 于2024年3月26日周二 23:25写道:

> On 2024-Mar-26, Tender Wang wrote:
>
> > postgres=# CREATE TABLE t1(c0 int, c1 int);
> > postgres=# ALTER TABLE t1 ADD CONSTRAINT Q PRIMARY KEY(c0, c1);
> > postgres=# ALTER TABLE t1 DROP c1;
> >
> > postgres=# ALTER TABLE t1 ALTER c0 DROP NOT NULL;
> > ERROR: could not find not-null constraint on column "c0", relation "t1"
>
> Ooh, hah, what happens here is that we drop the PK constraint
> indirectly, so we only go via doDeletion rather than the tablecmds.c
> code, so we don't check the attnotnull flags that the PK was protecting.
>

Yeah, Indeed, as you said.

> The attached patch is my workaround solution. Look forward your apply.
>
> Yeah, this is not a very good approach -- I think you're just guessing
> that the column is marked NOT NULL because a PK was dropped in the
> past -- but really what this catalog state is, is corrupted contents
> because the PK drop was mishandled. At least in theory there are other
> ways to drop a constraint other than dropping one of its columns (for
> example, maybe this could happen if you drop a collation that the PK
> depends on). The right approach is to ensure that the PK drop always
> does the dance that ATExecDropConstraint does. A good fix probably just
> moves some code from dropconstraint_internal to RemoveConstraintById.
>

Agreed. It is look better. But it will not work if simply move some codes
from dropconstraint_internal
to RemoveConstraintById. I have tried this fix before 0001 patch, but
failed.

For example:
create table skip_wal_skip_rewrite_index (c varchar(10) primary key);
alter table skip_wal_skip_rewrite_index alter c type varchar(20);
ERROR: primary key column "c" is not marked NOT NULL

index_check_primary_key() in index.c has below comments;

"We check for a pre-existing primary key, and that all columns of the index
are simple column references (not expressions), and that all those columns
are marked NOT NULL. If not, fail."

So in aboved example, RemoveConstraintById() can't reset attnotnull. We can
pass some information to
RemoveConstraintById() like a bool var to indicate that attnotnull should
be reset or not.

--
Tender Wang
OpenPie: https://en.openpie.com/

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message jian he 2024-03-27 03:41:50 Re: remaining sql/json patches
Previous Message shveta malik 2024-03-27 03:31:50 Re: Introduce XID age and inactive timeout based replication slot invalidation