Fix REPACK (CONCURRENTLY) for columns added without a table rewrite When applying the concurrent data changes, REPACK deformed the decoded tuples with the descriptor of the transient relation. That descriptor has no "missing" values, because make_new_heap() gives the transient relation none of the defaults and constraints of the source relation. A tuple written before an ALTER TABLE ... ADD COLUMN that did not rewrite the table has fewer attributes than the descriptor, so the missing values came out as NULL, even in a column declared NOT NULL. If such a value belongs to the replica identity, the key used to find the target tuple was NULL too, so the tuple to modify cannot not be found. The scan key does not remember that a value is NULL, so a pass-by-reference key would even crash the comparison function. Such tuples will be rare, because new row versions are normally formed with the current descriptor. A BEFORE ROW UPDATE trigger returning OLD is one way to produce one.
Fix by deforming the decoded tuples with the descriptor of the source relation, which does have the missing values. Tuples formed with it are still valid for the transient relation, whose attributes are a copy of the source relation ones. Commit 20d3fe9009dd took the same approach for INSERT and UPDATE in the executor. Expanding the decoded tuple with heap_expand_tuple() would be the other option, but that is the workaround of commit ba9f18abd that 20d3fe9009d got rid of, so do not bring it back. Add an isolation test. Author: Sami Imseih <[email protected]> Reported-by: Shihao Zhong <[email protected]> Reviewed-by: Kirill Reshke <[email protected]> Backpatch-through: 19 Discussion: https://postgr.es/m/CAN12+Y+NJwr5EqKVrHpPD=5+b_nraozu9fhrvdo3h46x2wr...@mail.gmail.com Branch ------ master Details ------- https://git.postgresql.org/pg/commitdiff/45da2c1d75663d7a692f967b77df42a84fdd6b4d Modified Files -------------- src/backend/commands/repack.c | 59 +++++++++++++---- src/backend/replication/pgrepack/pgrepack.c | 2 +- src/test/modules/injection_points/Makefile | 1 + .../expected/repack_missingval.out | 38 +++++++++++ src/test/modules/injection_points/meson.build | 1 + .../injection_points/specs/repack_missingval.spec | 74 ++++++++++++++++++++++ 6 files changed, 160 insertions(+), 15 deletions(-)
