diff options
| author | Noah Misch <noah@leadboat.com> | 2025-04-20 08:28:48 -0700 |
|---|---|---|
| committer | Noah Misch <noah@leadboat.com> | 2025-04-20 08:28:52 -0700 |
| commit | e0f53e6699697c24bbaccd8fd77e820e3e7f8248 (patch) | |
| tree | a7d89a89b38431f8cdf4510176233d2bb18ee5c0 /src/test | |
| parent | 90a3fd811edee14fcc2c105bd85d4d4948807f43 (diff) | |
Avoid ERROR at ON COMMIT DELETE ROWS after relhassubclass=f.
Commit 7102070329d8147246d2791321f9915c3b5abf31 fixed a similar bug, but
it missed the case of database-wide ANALYZE ("use_own_xacts" mode).
Commit a07e03fd8fa7daf4d1356f7cb501ffe784ea6257 changed consequences
from silent discard of a pg_class stats (relpages et al.) update to
ERROR "tuple to be updated was already modified". Losing a relpages
update of an ON COMMIT DELETE ROWS table was negligible, but a
COMMIT-time error isn't negligible. Back-patch to v13 (all supported
versions).
Reported-by: Richard Guo <guofenglinux@gmail.com
Reported-by: Robins Tharakan <tharakan@gmail.com>
Discussion: https://postgr.es/m/CAMbWs4-XwMKMKJ_GT=p3_-_=j9rQSEs1FbDFUnW9zHuKPsPNEQ@mail.gmail.com
Backpatch-through: 13
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/regress/expected/maintain_every.out | 33 | ||||
| -rw-r--r-- | src/test/regress/parallel_schedule | 4 | ||||
| -rw-r--r-- | src/test/regress/sql/maintain_every.sql | 26 |
3 files changed, 63 insertions, 0 deletions
diff --git a/src/test/regress/expected/maintain_every.out b/src/test/regress/expected/maintain_every.out new file mode 100644 index 00000000000..dea1089c249 --- /dev/null +++ b/src/test/regress/expected/maintain_every.out @@ -0,0 +1,33 @@ +-- Test maintenance commands that visit every eligible relation. Run as a +-- non-superuser, to skip other users' tables. +CREATE ROLE regress_maintain; +SET ROLE regress_maintain; +-- Test database-wide ANALYZE ("use_own_xacts" mode) setting relhassubclass=f +-- for non-partitioning inheritance, w/ ON COMMIT DELETE ROWS building an +-- empty index. +CREATE TEMP TABLE past_inh_db_other (); -- need 2 tables for "use_own_xacts" +CREATE TEMP TABLE past_inh_db_parent () ON COMMIT DELETE ROWS; +CREATE TEMP TABLE past_inh_db_child () INHERITS (past_inh_db_parent); +CREATE INDEX ON past_inh_db_parent ((1)); +ANALYZE past_inh_db_parent; +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_db_parent'::regclass; + reltuples | relhassubclass +-----------+---------------- + 0 | t +(1 row) + +DROP TABLE past_inh_db_child; +SET client_min_messages = error; -- hide WARNINGs for other users' tables +ANALYZE; +RESET client_min_messages; +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_db_parent'::regclass; + reltuples | relhassubclass +-----------+---------------- + 0 | f +(1 row) + +DROP TABLE past_inh_db_parent, past_inh_db_other; +RESET ROLE; +DROP ROLE regress_maintain; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 8157619a912..c54d9cb1d0e 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -99,6 +99,10 @@ test: select_parallel test: write_parallel test: vacuum_parallel +# Run this alone, because concurrent DROP TABLE would make non-superuser +# "ANALYZE;" fail with "relation with OID $n does not exist". +test: maintain_every + # no relation related tests can be put in this group test: publication subscription diff --git a/src/test/regress/sql/maintain_every.sql b/src/test/regress/sql/maintain_every.sql new file mode 100644 index 00000000000..263e97272d5 --- /dev/null +++ b/src/test/regress/sql/maintain_every.sql @@ -0,0 +1,26 @@ +-- Test maintenance commands that visit every eligible relation. Run as a +-- non-superuser, to skip other users' tables. + +CREATE ROLE regress_maintain; +SET ROLE regress_maintain; + +-- Test database-wide ANALYZE ("use_own_xacts" mode) setting relhassubclass=f +-- for non-partitioning inheritance, w/ ON COMMIT DELETE ROWS building an +-- empty index. +CREATE TEMP TABLE past_inh_db_other (); -- need 2 tables for "use_own_xacts" +CREATE TEMP TABLE past_inh_db_parent () ON COMMIT DELETE ROWS; +CREATE TEMP TABLE past_inh_db_child () INHERITS (past_inh_db_parent); +CREATE INDEX ON past_inh_db_parent ((1)); +ANALYZE past_inh_db_parent; +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_db_parent'::regclass; +DROP TABLE past_inh_db_child; +SET client_min_messages = error; -- hide WARNINGs for other users' tables +ANALYZE; +RESET client_min_messages; +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_db_parent'::regclass; +DROP TABLE past_inh_db_parent, past_inh_db_other; + +RESET ROLE; +DROP ROLE regress_maintain; |
