@@ -53,6 +53,7 @@ static corrupt_items *collect_corrupt_items(Oid relid, bool all_visible,
5353static void record_corrupt_item (corrupt_items * items , ItemPointer tid );
5454static bool tuple_all_visible (HeapTuple tup , TransactionId OldestXmin ,
5555 Buffer buffer );
56+ static void check_relation_relkind (Relation rel );
5657
5758/*
5859 * Visibility map information for a single block of a relation.
@@ -75,6 +76,9 @@ pg_visibility_map(PG_FUNCTION_ARGS)
7576
7677 rel = relation_open (relid , AccessShareLock );
7778
79+ /* Only some relkinds have a visibility map */
80+ check_relation_relkind (rel );
81+
7882 if (blkno < 0 || blkno > MaxBlockNumber )
7983 ereport (ERROR ,
8084 (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
@@ -114,6 +118,9 @@ pg_visibility(PG_FUNCTION_ARGS)
114118
115119 rel = relation_open (relid , AccessShareLock );
116120
121+ /* Only some relkinds have a visibility map */
122+ check_relation_relkind (rel );
123+
117124 if (blkno < 0 || blkno > MaxBlockNumber )
118125 ereport (ERROR ,
119126 (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
@@ -167,6 +174,7 @@ pg_visibility_map_rel(PG_FUNCTION_ARGS)
167174 funcctx = SRF_FIRSTCALL_INIT ();
168175 oldcontext = MemoryContextSwitchTo (funcctx -> multi_call_memory_ctx );
169176 funcctx -> tuple_desc = pg_visibility_tupdesc (true, false);
177+ /* collect_visibility_data will verify the relkind */
170178 funcctx -> user_fctx = collect_visibility_data (relid , false);
171179 MemoryContextSwitchTo (oldcontext );
172180 }
@@ -211,6 +219,7 @@ pg_visibility_rel(PG_FUNCTION_ARGS)
211219 funcctx = SRF_FIRSTCALL_INIT ();
212220 oldcontext = MemoryContextSwitchTo (funcctx -> multi_call_memory_ctx );
213221 funcctx -> tuple_desc = pg_visibility_tupdesc (true, true);
222+ /* collect_visibility_data will verify the relkind */
214223 funcctx -> user_fctx = collect_visibility_data (relid , true);
215224 MemoryContextSwitchTo (oldcontext );
216225 }
@@ -257,6 +266,10 @@ pg_visibility_map_summary(PG_FUNCTION_ARGS)
257266 bool nulls [2 ];
258267
259268 rel = relation_open (relid , AccessShareLock );
269+
270+ /* Only some relkinds have a visibility map */
271+ check_relation_relkind (rel );
272+
260273 nblocks = RelationGetNumberOfBlocks (rel );
261274
262275 for (blkno = 0 ; blkno < nblocks ; ++ blkno )
@@ -309,6 +322,7 @@ pg_check_frozen(PG_FUNCTION_ARGS)
309322
310323 funcctx = SRF_FIRSTCALL_INIT ();
311324 oldcontext = MemoryContextSwitchTo (funcctx -> multi_call_memory_ctx );
325+ /* collect_corrupt_items will verify the relkind */
312326 funcctx -> user_fctx = collect_corrupt_items (relid , false, true);
313327 MemoryContextSwitchTo (oldcontext );
314328 }
@@ -340,6 +354,7 @@ pg_check_visible(PG_FUNCTION_ARGS)
340354
341355 funcctx = SRF_FIRSTCALL_INIT ();
342356 oldcontext = MemoryContextSwitchTo (funcctx -> multi_call_memory_ctx );
357+ /* collect_corrupt_items will verify the relkind */
343358 funcctx -> user_fctx = collect_corrupt_items (relid , true, false);
344359 MemoryContextSwitchTo (oldcontext );
345360 }
@@ -369,13 +384,8 @@ pg_truncate_visibility_map(PG_FUNCTION_ARGS)
369384
370385 rel = relation_open (relid , AccessExclusiveLock );
371386
372- if (rel -> rd_rel -> relkind != RELKIND_RELATION &&
373- rel -> rd_rel -> relkind != RELKIND_MATVIEW &&
374- rel -> rd_rel -> relkind != RELKIND_TOASTVALUE )
375- ereport (ERROR ,
376- (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
377- errmsg ("\"%s\" is not a table, materialized view, or TOAST table" ,
378- RelationGetRelationName (rel ))));
387+ /* Only some relkinds have a visibility map */
388+ check_relation_relkind (rel );
379389
380390 RelationOpenSmgr (rel );
381391 rel -> rd_smgr -> smgr_vm_nblocks = InvalidBlockNumber ;
@@ -451,6 +461,9 @@ pg_visibility_tupdesc(bool include_blkno, bool include_pd)
451461
452462/*
453463 * Collect visibility data about a relation.
464+ *
465+ * Checks relkind of relid and will throw an error if the relation does not
466+ * have a VM.
454467 */
455468static vbits *
456469collect_visibility_data (Oid relid , bool include_pd )
@@ -464,6 +477,9 @@ collect_visibility_data(Oid relid, bool include_pd)
464477
465478 rel = relation_open (relid , AccessShareLock );
466479
480+ /* Only some relkinds have a visibility map */
481+ check_relation_relkind (rel );
482+
467483 nblocks = RelationGetNumberOfBlocks (rel );
468484 info = palloc0 (offsetof(vbits , bits ) + nblocks );
469485 info -> next = 0 ;
@@ -523,6 +539,9 @@ collect_visibility_data(Oid relid, bool include_pd)
523539 *
524540 * If all_frozen is passed as true, this will include all items which are
525541 * on pages marked as all-frozen but which do not seem to in fact be frozen.
542+ *
543+ * Checks relkind of relid and will throw an error if the relation does not
544+ * have a VM.
526545 */
527546static corrupt_items *
528547collect_corrupt_items (Oid relid , bool all_visible , bool all_frozen )
@@ -543,13 +562,8 @@ collect_corrupt_items(Oid relid, bool all_visible, bool all_frozen)
543562
544563 rel = relation_open (relid , AccessShareLock );
545564
546- if (rel -> rd_rel -> relkind != RELKIND_RELATION &&
547- rel -> rd_rel -> relkind != RELKIND_MATVIEW &&
548- rel -> rd_rel -> relkind != RELKIND_TOASTVALUE )
549- ereport (ERROR ,
550- (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
551- errmsg ("\"%s\" is not a table, materialized view, or TOAST table" ,
552- RelationGetRelationName (rel ))));
565+ /* Only some relkinds have a visibility map */
566+ check_relation_relkind (rel );
553567
554568 nblocks = RelationGetNumberOfBlocks (rel );
555569
@@ -747,3 +761,19 @@ tuple_all_visible(HeapTuple tup, TransactionId OldestXmin, Buffer buffer)
747761
748762 return true;
749763}
764+
765+ /*
766+ * check_relation_relkind - convenience routine to check that relation
767+ * is of the relkind supported by the callers
768+ */
769+ static void
770+ check_relation_relkind (Relation rel )
771+ {
772+ if (rel -> rd_rel -> relkind != RELKIND_RELATION &&
773+ rel -> rd_rel -> relkind != RELKIND_MATVIEW &&
774+ rel -> rd_rel -> relkind != RELKIND_TOASTVALUE )
775+ ereport (ERROR ,
776+ (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
777+ errmsg ("\"%s\" is not a table, materialized view, or TOAST table" ,
778+ RelationGetRelationName (rel ))));
779+ }
0 commit comments