@@ -53,6 +53,7 @@ static corrupt_items *collect_corrupt_items(Oid relid, bool all_visible,
53
53
static void record_corrupt_item (corrupt_items * items , ItemPointer tid );
54
54
static bool tuple_all_visible (HeapTuple tup , TransactionId OldestXmin ,
55
55
Buffer buffer );
56
+ static void check_relation_relkind (Relation rel );
56
57
57
58
/*
58
59
* Visibility map information for a single block of a relation.
@@ -75,6 +76,9 @@ pg_visibility_map(PG_FUNCTION_ARGS)
75
76
76
77
rel = relation_open (relid , AccessShareLock );
77
78
79
+ /* Only some relkinds have a visibility map */
80
+ check_relation_relkind (rel );
81
+
78
82
if (blkno < 0 || blkno > MaxBlockNumber )
79
83
ereport (ERROR ,
80
84
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
@@ -114,6 +118,9 @@ pg_visibility(PG_FUNCTION_ARGS)
114
118
115
119
rel = relation_open (relid , AccessShareLock );
116
120
121
+ /* Only some relkinds have a visibility map */
122
+ check_relation_relkind (rel );
123
+
117
124
if (blkno < 0 || blkno > MaxBlockNumber )
118
125
ereport (ERROR ,
119
126
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
@@ -167,6 +174,7 @@ pg_visibility_map_rel(PG_FUNCTION_ARGS)
167
174
funcctx = SRF_FIRSTCALL_INIT ();
168
175
oldcontext = MemoryContextSwitchTo (funcctx -> multi_call_memory_ctx );
169
176
funcctx -> tuple_desc = pg_visibility_tupdesc (true, false);
177
+ /* collect_visibility_data will verify the relkind */
170
178
funcctx -> user_fctx = collect_visibility_data (relid , false);
171
179
MemoryContextSwitchTo (oldcontext );
172
180
}
@@ -211,6 +219,7 @@ pg_visibility_rel(PG_FUNCTION_ARGS)
211
219
funcctx = SRF_FIRSTCALL_INIT ();
212
220
oldcontext = MemoryContextSwitchTo (funcctx -> multi_call_memory_ctx );
213
221
funcctx -> tuple_desc = pg_visibility_tupdesc (true, true);
222
+ /* collect_visibility_data will verify the relkind */
214
223
funcctx -> user_fctx = collect_visibility_data (relid , true);
215
224
MemoryContextSwitchTo (oldcontext );
216
225
}
@@ -257,6 +266,10 @@ pg_visibility_map_summary(PG_FUNCTION_ARGS)
257
266
bool nulls [2 ];
258
267
259
268
rel = relation_open (relid , AccessShareLock );
269
+
270
+ /* Only some relkinds have a visibility map */
271
+ check_relation_relkind (rel );
272
+
260
273
nblocks = RelationGetNumberOfBlocks (rel );
261
274
262
275
for (blkno = 0 ; blkno < nblocks ; ++ blkno )
@@ -309,6 +322,7 @@ pg_check_frozen(PG_FUNCTION_ARGS)
309
322
310
323
funcctx = SRF_FIRSTCALL_INIT ();
311
324
oldcontext = MemoryContextSwitchTo (funcctx -> multi_call_memory_ctx );
325
+ /* collect_corrupt_items will verify the relkind */
312
326
funcctx -> user_fctx = collect_corrupt_items (relid , false, true);
313
327
MemoryContextSwitchTo (oldcontext );
314
328
}
@@ -340,6 +354,7 @@ pg_check_visible(PG_FUNCTION_ARGS)
340
354
341
355
funcctx = SRF_FIRSTCALL_INIT ();
342
356
oldcontext = MemoryContextSwitchTo (funcctx -> multi_call_memory_ctx );
357
+ /* collect_corrupt_items will verify the relkind */
343
358
funcctx -> user_fctx = collect_corrupt_items (relid , true, false);
344
359
MemoryContextSwitchTo (oldcontext );
345
360
}
@@ -369,13 +384,8 @@ pg_truncate_visibility_map(PG_FUNCTION_ARGS)
369
384
370
385
rel = relation_open (relid , AccessExclusiveLock );
371
386
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 );
379
389
380
390
RelationOpenSmgr (rel );
381
391
rel -> rd_smgr -> smgr_vm_nblocks = InvalidBlockNumber ;
@@ -451,6 +461,9 @@ pg_visibility_tupdesc(bool include_blkno, bool include_pd)
451
461
452
462
/*
453
463
* 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.
454
467
*/
455
468
static vbits *
456
469
collect_visibility_data (Oid relid , bool include_pd )
@@ -464,6 +477,9 @@ collect_visibility_data(Oid relid, bool include_pd)
464
477
465
478
rel = relation_open (relid , AccessShareLock );
466
479
480
+ /* Only some relkinds have a visibility map */
481
+ check_relation_relkind (rel );
482
+
467
483
nblocks = RelationGetNumberOfBlocks (rel );
468
484
info = palloc0 (offsetof(vbits , bits ) + nblocks );
469
485
info -> next = 0 ;
@@ -523,6 +539,9 @@ collect_visibility_data(Oid relid, bool include_pd)
523
539
*
524
540
* If all_frozen is passed as true, this will include all items which are
525
541
* 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.
526
545
*/
527
546
static corrupt_items *
528
547
collect_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)
543
562
544
563
rel = relation_open (relid , AccessShareLock );
545
564
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 );
553
567
554
568
nblocks = RelationGetNumberOfBlocks (rel );
555
569
@@ -747,3 +761,19 @@ tuple_all_visible(HeapTuple tup, TransactionId OldestXmin, Buffer buffer)
747
761
748
762
return true;
749
763
}
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