Subject: [PATCH v3] Avoid errors in brin summarization..

From: Alvaro Herrera <[email-masked]>
Date: Fri, 13 Nov 2020 13:39:31 -0300

..which can happen if an index is reindexed concurrently
---
 src/backend/access/brin/brin.c     | 22 +++++++++++++++-------
 src/test/regress/expected/brin.out |  6 +++++-
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index 1f72562c60..46e5269260 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -887,16 +887,24 @@ brin_summarize_range(PG_FUNCTION_ARGS)
 	/*
 	 * We must lock table before index to avoid deadlocks.  However, if the
 	 * passed indexoid isn't an index then IndexGetRelation() will fail.
-	 * Rather than emitting a not-very-helpful error message, postpone
-	 * complaining, expecting that the is-it-an-index test below will fail.
+	 * Rather than emitting a not-very-helpful error message, prepare to
+	 * return without doing anything.  This allows autovacuum work-items to be
+	 * silently discarded rather than uselessly accumulating error messages in
+	 * the server log.
 	 */
 	heapoid = IndexGetRelation(indexoid, true);
-	if (OidIsValid(heapoid))
-		heapRel = table_open(heapoid, ShareUpdateExclusiveLock);
-	else
-		heapRel = NULL;
+	heapRel = OidIsValid(heapoid) ?
+		table_open(heapoid, ShareUpdateExclusiveLock) : NULL;
 
-	indexRel = index_open(indexoid, ShareUpdateExclusiveLock);
+	if (heapRel == NULL)
+		PG_RETURN_INT32(0);
+
+	indexRel = try_relation_open(indexoid, ShareUpdateExclusiveLock);
+	if (indexRel == NULL)
+	{
+		table_close(heapRel, ShareUpdateExclusiveLock);
+		PG_RETURN_INT32(0);
+	}
 
 	/* Must be a BRIN index */
 	if (indexRel->rd_rel->relkind != RELKIND_INDEX ||
diff --git a/src/test/regress/expected/brin.out b/src/test/regress/expected/brin.out
index e53d6e4885..51dff7295d 100644
--- a/src/test/regress/expected/brin.out
+++ b/src/test/regress/expected/brin.out
@@ -405,7 +405,11 @@ UPDATE brintest SET int8col = int8col * int4col;
 UPDATE brintest SET textcol = '' WHERE textcol IS NOT NULL;
 -- Tests for brin_summarize_new_values
 SELECT brin_summarize_new_values('brintest'); -- error, not an index
-ERROR:  "brintest" is not an index
+ brin_summarize_new_values 
+---------------------------
+                         0
+(1 row)
+
 SELECT brin_summarize_new_values('tenk1_unique1'); -- error, not a BRIN index
 ERROR:  "tenk1_unique1" is not a BRIN index
 SELECT brin_summarize_new_values('brinidx'); -- ok, no change expected
-- 
2.17.0

--lQSB8Tqijvu1+4Ba--