Re: bug when apply fast default mechanism for adding new column over domain with default value

Tender Wang <tndrwang@gmail.com>

From: Tender Wang <tndrwang@gmail.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Alexander Lakhin <exclusion@gmail.com>, jian he <jian.universality@gmail.com>, PostgreSQL-development <pgsql-hackers@postgresql.org>
Date: 2025-04-02T02:01:31Z
Lists: pgsql-hackers

Attachments

Tom Lane <tgl@sss.pgh.pa.us> 于2025年4月2日周三 09:05写道:

> Alexander Lakhin <exclusion@gmail.com> writes:
> > I've discovered that 95f650674 introduced a defect similar to bug #18297,
> > but this time with DEFAULT. Namely, the following script:
> > CREATE TABLE a (aa text);
> > CREATE TABLE c (cc text) INHERITS (a);
> > CREATE TABLE d (dd text) INHERITS (c, a);
> > ALTER TABLE a ADD COLUMN i int DEFAULT 1;
>
> > fails with:
> > ERROR:  XX000: tuple already updated by self
> > LOCATION:  simple_heap_update, heapam.c:4421
>
> Hmm, yeah.  The failing call is here:
>
>             /* Bump the existing child att's inhcount */
>             ...
>             CatalogTupleUpdate(attrdesc, &tuple->t_self, tuple);
>
> so I think you're right that that code path is now short a
> CommandCounterIncrement() somewhere.  I'll look tomorrow if
> nobody beats me to it.
>

Yes, when table a process its children, which are table c and table d.
Table c is first to be done.
At the same time, table d is also child of table c, so after updating own
pg_attribute tuple, table c will
process its child table d. And table d update its pg_attribute catalog
tuple.

After finishing table c, the logic returning to continue to process table
a's children, which this time is table d.
Between table d pg_attribute tuple updated as child of table c and updating
table d pg_attribute tuple again as child of table a,
there is no call CommandCounterIncrement().

So let's add CommandCounterIncrement() after calling StoreAttrMissingVal().


-- 
Thanks, Tender Wang

Commits

  1. Need to do CommandCounterIncrement after StoreAttrMissingVal.

  2. Simplify some logic around setting pg_attribute.atthasdef.

  3. Remove now-dead code in StoreAttrDefault().

  4. Fix broken handling of domains in atthasmissing logic.