[Bug]Vacuum full silently NULL out fast default columns - Mailing list pgsql-hackers

From SATYANARAYANA NARLAPURAM
Subject [Bug]Vacuum full silently NULL out fast default columns
Date
Msg-id CAHg+QDeoccU5CudrJpmSKZfKZ1gRMNY=5BxSC=JpHgkonzgcOw@mail.gmail.com
Whole thread
Responses Re: [Bug]Vacuum full silently NULL out fast default columns
List pgsql-hackers
Hi Hackers,

VACUUM FULL silently turns columns added via ALTER TABLE ... ADD COLUMN ... DEFAULT <const> into NULL
on all pre-existing rows. The issue exists for other operations like CLUSTER, REPACK.

Repro:

CREATE TABLE t (id int PRIMARY KEY);
INSERT INTO t SELECT generate_series(1,3);
ALTER TABLE t ADD COLUMN x int DEFAULT 42;
SELECT * FROM t;     -- (1,42),(2,42),(3,42)
VACUUM FULL t;
SELECT * FROM t;     -- (1,NULL),(2,NULL),(3,NULL)

If the column is NOT NULL, the value becomes the type's zero value
instead of NULL, silently bypassing both NOT NULL and any CHECK
constraint declared on it.

Root Cause: fast path in reform_tuple() in heapam_handler.c returns a copy
of the source tuple when no dropped columns need fixing up. The check
doesn't account for short tuples (HeapTupleHeaderGetNatts(t) <
relnatts) that rely on attmissingval to materialize the default. After
the rewrite, finish_heap_swap() calls RelationClearMissing(), clearing
the only source of those values, and the short tuples then read as
NULL.


Fix: force reform when the source tuple is shorter than the new tuple
descriptor.

Patch attached. Added a regression test in fast_default.sql covering
VACUUM FULL, CLUSTER, and REPACK on a table with fast-default columns
including a NOT NULL CHECK column.

Thanks,
Satya
Attachment

pgsql-hackers by date:

Previous
From: shveta malik
Date:
Subject: Re: Proposal: Conflict log history table for Logical Replication
Next
From: Dilip Kumar
Date:
Subject: Re: Proposal: Conflict log history table for Logical Replication