Fix timing issue with ALTER TABLE's validate constraint
authorDavid Rowley <[email protected]>
Tue, 14 Jul 2020 05:01:25 +0000 (17:01 +1200)
committerDavid Rowley <[email protected]>
Tue, 14 Jul 2020 05:01:25 +0000 (17:01 +1200)
commite20003fa0f8d35fa03bc60273e1cee4558f19e41
treeed29364da462fdc273c9b43d9e0e4417dd742aef
parent80d8f6d1d6338c335c84048e65e1203fada863b2
Fix timing issue with ALTER TABLE's validate constraint

An ALTER TABLE to validate a foreign key in which another subcommand
already caused a pending table rewrite could fail due to ALTER TABLE
attempting to validate the foreign key before the actual table rewrite
takes place.  This situation could result in an error such as:

ERROR:  could not read block 0 in file "base/nnnnn/nnnnn": read only 0 of 8192 bytes

The failure here was due to the SPI call which validates the foreign key
trying to access an index which is yet to be rebuilt.

Similarly, we also incorrectly tried to validate CHECK constraints before
the heap had been rewritten.

The fix for both is to delay constraint validation until phase 3, after
the table has been rewritten.  For CHECK constraints this means a slight
behavioral change.  Previously ALTER TABLE VALIDATE CONSTRAINT on
inheritance tables would be validated from the bottom up.  This was
different from the order of evaluation when a new CHECK constraint was
added.  The changes made here aligns the VALIDATE CONSTRAINT evaluation
order for inheritance tables to be the same as ADD CONSTRAINT, which is
generally top-down.

Reported-by: Nazli Ugur Koyluoglu, using SQLancer
Discussion: https://postgr.es/m/CAApHDvp%3DZXv8wiRyk_0rWr00skhGkt8vXDrHJYXRMft3TjkxCA%40mail.gmail.com
Backpatch-through: 9.5 (all supported versions)
src/backend/commands/tablecmds.c
src/test/regress/expected/alter_table.out
src/test/regress/sql/alter_table.sql