Fix ALTER TABLE .. ADD COLUMN with complex inheritance trees

This command, when used to add a column on a parent table with a complex
inheritance tree, tried to update multiple times the same tuple in
pg_attribute for a child table when incrementing attinhcount, causing
failures with "tuple already updated by self" because of a missing
CommandCounterIncrement() between two updates.

This exists for a rather long time, so backpatch all the way down.

Reported-by: Alexander Lakhin
Author: Tender Wang
Reviewed-by: Richard Guo
Discussion: https://postgr.es/m/18297-b04cd83a55b51e35@postgresql.org
Backpatch-through: 12
This commit is contained in:
Michael Paquier 2024-01-24 14:20:14 +09:00
parent 8103822858
commit 2f72428371
3 changed files with 30 additions and 0 deletions

View File

@ -6001,6 +6001,10 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
colDef->colname, RelationGetRelationName(rel))));
table_close(attrdesc, RowExclusiveLock);
/* Make the child column change visible */
CommandCounterIncrement();
return InvalidObjectAddress;
}
}

View File

@ -1063,6 +1063,23 @@ Inherits: inht1,
inhs1
DROP TABLE inhts;
-- Test for adding a column to a parent table with complex inheritance
CREATE TABLE inhta ();
CREATE TABLE inhtb () INHERITS (inhta);
CREATE TABLE inhtc () INHERITS (inhtb);
CREATE TABLE inhtd () INHERITS (inhta, inhtb, inhtc);
ALTER TABLE inhta ADD COLUMN i int;
NOTICE: merging definition of column "i" for child "inhtd"
NOTICE: merging definition of column "i" for child "inhtd"
\d+ inhta
Table "public.inhta"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+---------+--------------+-------------
i | integer | | | | plain | |
Child tables: inhtb,
inhtd
DROP TABLE inhta, inhtb, inhtc, inhtd;
-- Test for renaming in diamond inheritance
CREATE TABLE inht2 (x int) INHERITS (inht1);
CREATE TABLE inht3 (y int) INHERITS (inht1);

View File

@ -353,6 +353,15 @@ ALTER TABLE inhts RENAME d TO dd;
DROP TABLE inhts;
-- Test for adding a column to a parent table with complex inheritance
CREATE TABLE inhta ();
CREATE TABLE inhtb () INHERITS (inhta);
CREATE TABLE inhtc () INHERITS (inhtb);
CREATE TABLE inhtd () INHERITS (inhta, inhtb, inhtc);
ALTER TABLE inhta ADD COLUMN i int;
\d+ inhta
DROP TABLE inhta, inhtb, inhtc, inhtd;
-- Test for renaming in diamond inheritance
CREATE TABLE inht2 (x int) INHERITS (inht1);
CREATE TABLE inht3 (y int) INHERITS (inht1);