| From: | Andrey Borodin <x4mmm(at)yandex-team(dot)ru> |
|---|---|
| To: | Matthias van de Meent <boekewurm(at)gmail(dot)com> |
| Cc: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Peter Eisentraut <peter(at)eisentraut(dot)org> |
| Subject: | Re: Bug: Whole-row var in indexes corrupts indexes after DDL |
| Date: | 2026-08-23 11:25:48 |
| Message-ID: | BEE8820C-50BD-467A-BDBC-F95827D737EB@yandex-team.ru |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi Matthias,
Thanks for working on this! I took a look into v1.
First, with v1 applied, a statement with shape changes in more than one
ALTER TABLE pass fails:
CREATE TABLE t(a int, b int);
CREATE FUNCTION f(t) RETURNS t
LANGUAGE sql IMMUTABLE RETURN $1;
CREATE INDEX t_idx ON t ((f(t)));
ALTER TABLE t ADD COLUMN c int, DROP COLUMN b;
ERROR: cache lookup failed for index ...
ATPostAlterTypeCleanup() runs after both AT_PASS_ADD_COL and
AT_PASS_DROP. The first call drops the index, but its OID remains in
tab->changedIndexOids, so the second call tries to process it again.
This appears to be the same underlying issue that Jian He reported for
ALTER TYPE combined with SET EXPRESSION [0]. The new cleanup calls make
ADD COLUMN combined with DROP COLUMN hit it too.
Second, a whole-row partition expression can still leave a table
mispartitioned. Its self-dependency is reversed, so looking for objects
that depend on WholeRowAttrNumber does not find the partition key. In
my test, adding a nullable column changed the partition key of an
existing row from 1 to 0. The old row remained in partition 1, while a
new row was routed to partition 0. Perhaps shape-changing DDL should be
rejected when a partition key contains a whole-row reference.
Rebuilding the expression would not move existing rows between
partitions.
There also seems to be a regression for whole-row Vars referencing an
RTE_FUNCTION. find_expr_references_walker() now passes
WholeRowAttrNumber to process_function_rte_ref(), but that function
expects a positive output-column number. It therefore falls through to:
ERROR: column -32768 of relation "..." does not exist
The new pseudo-subobject needs handling in the rest of the object
address API too. pg_describe_object() reports it correctly, but
pg_identify_object() and pg_identify_object_as_address() currently call
it a "table column" and produce an empty identity.
Some smaller points:
* ATExecAddColumn() calls RememberWholeRowDependentForRebuilding()
twice.
* ATExecAlterColumnType() passes AT_AddColumn to that function.
I think the regression test should also compare the result of the
original partial-index query using an index scan and a sequential scan.
Checking only that relfilenode changes would not detect a rebuild that
still produces an incorrect index. The combined ALTER TABLE and
partition-key cases above would also be useful. I attached the complete
reproducers.
For the record, an AI-assisted grep over the Hackorum archive puts the
virtual generated-column case (a4639d64e2) mentioned in the opening
message into a longer sequence: a unique whole-row index becoming
inconsistent after DROP COLUMN in 2020 [1], hash_record() indexes after
ADD or DROP COLUMN in 2023 [2], the work on whole-row dependencies for
DROP COLUMN and ALTER TYPE [3], the virtual generated-column case [4],
and rebuilding whole-row CHECK constraints after SET EXPRESSION [5].
This seems like good evidence that the general dependency is worth
representing, rather than fixing each new manifestation separately.
Thank you!
Best regards, Andrey Borodin.
[0] https://postgr.es/m/CACJufxHZsgn3zM5g-x7YmtFGzNDnRwR07S+GYfiUs+tZ45MDDw@mail.gmail.com
[1] https://postgr.es/m/e48a5d9a2d3d72985d61ee254314f5f5f5444a55.camel@cybertec.at
[2] https://postgr.es/m/18244-8a7897de2acd5a08@postgresql.org
[3] https://postgr.es/m/CACJufxGA6KVQy7DbHGLVw9s9KKmpGyZt5ME6C7kEfjDpr2wZCw@mail.gmail.com
[4] https://postgr.es/m/CAJTYsWVmfHyooKCj30suW8=Y6b8be7WcyYmuAKMD=2mTPFpDkg@mail.gmail.com
[5] https://postgr.es/m/CAJTYsWXOkyeDVbzymWc9sKrq7Y_MUv6XJXN4H9GfsBOPd3NJ+w@mail.gmail.com
| From | Date | Subject | |
|---|---|---|---|
| Previous Message | bd_reiss | 2026-08-23 10:37:02 | Re: missing possibility to use alternative translated month names in to_char function |