Promote assertion about !ReindexIsProcessingIndex to runtime error.

When this assertion was installed (in commit d2f60a3ab), I thought
it was only for catching server logic errors that caused accesses to
catalogs that were undergoing index rebuilds.  However, it will also
fire in case of a user-defined index expression that attempts to
access its own table.  We occasionally see reports of people trying
to do that, and typically getting unintelligible low-level errors
as a result.  We can provide a more on-point message by making this
a regular runtime check.

While at it, adjust the similar error check in
systable_beginscan_ordered to use the same message text.  That one
is (probably) not reachable without a coding bug, but we might as
well use a translatable message if we have one.

Per bug #18363 from Alexander Lakhin.  Back-patch to all supported
branches.

Discussion: https://postgr.es/m/18363-e3598a5a572d0699@postgresql.org
This commit is contained in:
Tom Lane 2024-02-25 16:15:07 -05:00
parent b3b3effca6
commit 8c785d354c
2 changed files with 15 additions and 8 deletions

View File

@ -653,8 +653,10 @@ systable_beginscan_ordered(Relation heapRelation,
/* REINDEX can probably be a hard error here ... */ /* REINDEX can probably be a hard error here ... */
if (ReindexIsProcessingIndex(RelationGetRelid(indexRelation))) if (ReindexIsProcessingIndex(RelationGetRelid(indexRelation)))
elog(ERROR, "cannot do ordered scan on index \"%s\", because it is being reindexed", ereport(ERROR,
RelationGetRelationName(indexRelation)); (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot access index \"%s\" while it is being reindexed",
RelationGetRelationName(indexRelation))));
/* ... but we only throw a warning about violating IgnoreSystemIndexes */ /* ... but we only throw a warning about violating IgnoreSystemIndexes */
if (IgnoreSystemIndexes) if (IgnoreSystemIndexes)
elog(WARNING, "using index \"%s\" despite IgnoreSystemIndexes", elog(WARNING, "using index \"%s\" despite IgnoreSystemIndexes",

View File

@ -70,18 +70,23 @@
* Note: the ReindexIsProcessingIndex() check in RELATION_CHECKS is there * Note: the ReindexIsProcessingIndex() check in RELATION_CHECKS is there
* to check that we don't try to scan or do retail insertions into an index * to check that we don't try to scan or do retail insertions into an index
* that is currently being rebuilt or pending rebuild. This helps to catch * that is currently being rebuilt or pending rebuild. This helps to catch
* things that don't work when reindexing system catalogs. The assertion * things that don't work when reindexing system catalogs, as well as prevent
* user errors like index expressions that access their own tables. The check
* doesn't prevent the actual rebuild because we don't use RELATION_CHECKS * doesn't prevent the actual rebuild because we don't use RELATION_CHECKS
* when calling the index AM's ambuild routine, and there is no reason for * when calling the index AM's ambuild routine, and there is no reason for
* ambuild to call its subsidiary routines through this file. * ambuild to call its subsidiary routines through this file.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
#define RELATION_CHECKS \ #define RELATION_CHECKS \
( \ do { \
AssertMacro(RelationIsValid(indexRelation)), \ Assert(RelationIsValid(indexRelation)); \
AssertMacro(PointerIsValid(indexRelation->rd_indam)), \ Assert(PointerIsValid(indexRelation->rd_indam)); \
AssertMacro(!ReindexIsProcessingIndex(RelationGetRelid(indexRelation))) \ if (unlikely(ReindexIsProcessingIndex(RelationGetRelid(indexRelation)))) \
) ereport(ERROR, \
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
errmsg("cannot access index \"%s\" while it is being reindexed", \
RelationGetRelationName(indexRelation)))); \
} while(0)
#define SCAN_CHECKS \ #define SCAN_CHECKS \
( \ ( \