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

> Alexander Lakhin <exclus...@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
From ee2bc290cab83daf0ebecf9f29cc23539ba19741 Mon Sep 17 00:00:00 2001
From: Tender Wang <tndrw...@gmail.com>
Date: Wed, 2 Apr 2025 09:52:22 +0800
Subject: [PATCH] Fix "tuple already updated by self" issue.

---
 src/backend/commands/tablecmds.c      |  2 ++
 src/test/regress/expected/inherit.out | 17 +++++++++++++++++
 src/test/regress/sql/inherit.sql      |  8 ++++++++
 3 files changed, 27 insertions(+)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 10624353b0a..67e0aabf4a7 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -7518,6 +7518,8 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, 
Relation rel,
                                {
                                        StoreAttrMissingVal(rel, 
attribute->attnum, missingval);
                                        has_missing = true;
+                                       /* Make above changes visible */
+                                       CommandCounterIncrement();
                                }
                                FreeExecutorState(estate);
                        }
diff --git a/src/test/regress/expected/inherit.out 
b/src/test/regress/expected/inherit.out
index 4d07d0bd79b..ba4327e7acb 100644
--- a/src/test/regress/expected/inherit.out
+++ b/src/test/regress/expected/inherit.out
@@ -1108,6 +1108,23 @@ Child tables: inhtb,
               inhtd
 
 DROP TABLE inhta, inhtb, inhtc, inhtd;
+-- Test for adding a column wiht DEFAULT value
+CREATE TABLE inhtda (aa text);
+CREATE TABLE inhtdc (cc text) INHERITS (inhtda);
+CREATE TABLE inhtdd (dd text) INHERITS (inhtdc, inhtda);
+NOTICE:  merging multiple inherited definitions of column "aa"
+ALTER TABLE inhtda ADD COLUMN i int DEFAULT 1;
+NOTICE:  merging definition of column "i" for child "inhtdd"
+\d+ inhtda
+                                   Table "public.inhtda"
+ Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | 
Description 
+--------+---------+-----------+----------+---------+----------+--------------+-------------
+ aa     | text    |           |          |         | extended |              | 
+ i      | integer |           |          | 1       | plain    |              | 
+Child tables: inhtdc,
+              inhtdd
+
+DROP TABLE inhtda, inhtdc, inhtdd;
 -- Test for renaming in diamond inheritance
 CREATE TABLE inht2 (x int) INHERITS (inht1);
 CREATE TABLE inht3 (y int) INHERITS (inht1);
diff --git a/src/test/regress/sql/inherit.sql b/src/test/regress/sql/inherit.sql
index 941189761fd..d9fd6340798 100644
--- a/src/test/regress/sql/inherit.sql
+++ b/src/test/regress/sql/inherit.sql
@@ -384,6 +384,14 @@ ALTER TABLE inhta ADD COLUMN i int;
 \d+ inhta
 DROP TABLE inhta, inhtb, inhtc, inhtd;
 
+-- Test for adding a column wiht DEFAULT value
+CREATE TABLE inhtda (aa text);
+CREATE TABLE inhtdc (cc text) INHERITS (inhtda);
+CREATE TABLE inhtdd (dd text) INHERITS (inhtdc, inhtda);
+ALTER TABLE inhtda ADD COLUMN i int DEFAULT 1;
+\d+ inhtda
+DROP TABLE inhtda, inhtdc, inhtdd;
+
 -- Test for renaming in diamond inheritance
 CREATE TABLE inht2 (x int) INHERITS (inht1);
 CREATE TABLE inht3 (y int) INHERITS (inht1);
-- 
2.34.1

Reply via email to