Coverage Report

Created: 2026-08-13 07:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/include/access/heapam.h
Line
Count
Source
1
/*-------------------------------------------------------------------------
2
 *
3
 * heapam.h
4
 *    POSTGRES heap access method definitions.
5
 *
6
 *
7
 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
8
 * Portions Copyright (c) 1994, Regents of the University of California
9
 *
10
 * src/include/access/heapam.h
11
 *
12
 *-------------------------------------------------------------------------
13
 */
14
#ifndef HEAPAM_H
15
#define HEAPAM_H
16
17
#include "access/heapam_xlog.h"
18
#include "access/relation.h"  /* for backward compatibility */
19
#include "access/relscan.h"
20
#include "access/sdir.h"
21
#include "access/skey.h"
22
#include "access/table.h"   /* for backward compatibility */
23
#include "access/tableam.h"
24
#include "nodes/lockoptions.h"
25
#include "nodes/primnodes.h"
26
#include "storage/bufpage.h"
27
#include "storage/dsm.h"
28
#include "storage/lockdefs.h"
29
#include "storage/read_stream.h"
30
#include "storage/shm_toc.h"
31
#include "utils/relcache.h"
32
#include "utils/snapshot.h"
33
34
35
/* "options" flag bits for heap_insert */
36
0
#define HEAP_INSERT_SKIP_FSM  TABLE_INSERT_SKIP_FSM
37
0
#define HEAP_INSERT_FROZEN    TABLE_INSERT_FROZEN
38
0
#define HEAP_INSERT_NO_LOGICAL  TABLE_INSERT_NO_LOGICAL
39
0
#define HEAP_INSERT_SPECULATIVE 0x0010
40
41
/* "options" flag bits for heap_page_prune_and_freeze */
42
0
#define HEAP_PAGE_PRUNE_MARK_UNUSED_NOW   (1 << 0)
43
0
#define HEAP_PAGE_PRUNE_FREEZE        (1 << 1)
44
0
#define HEAP_PAGE_PRUNE_ALLOW_FAST_PATH   (1 << 2)
45
0
#define HEAP_PAGE_PRUNE_SET_VM        (1 << 3)
46
47
typedef struct BulkInsertStateData *BulkInsertState;
48
typedef struct GlobalVisState GlobalVisState;
49
typedef struct TupleTableSlot TupleTableSlot;
50
typedef struct VacuumCutoffs VacuumCutoffs;
51
typedef struct VacuumParams VacuumParams;
52
53
#define MaxLockTupleMode  LockTupleExclusive
54
55
/*
56
 * Descriptor for heap table scans.
57
 */
58
typedef struct HeapScanDescData
59
{
60
  TableScanDescData rs_base;  /* AM independent part of the descriptor */
61
62
  /* state set up at initscan time */
63
  BlockNumber rs_nblocks;   /* total number of blocks in rel */
64
  BlockNumber rs_startblock;  /* block # to start at */
65
  BlockNumber rs_numblocks; /* max number of blocks to scan */
66
  /* rs_numblocks is usually InvalidBlockNumber, meaning "scan whole rel" */
67
68
  /* scan current state */
69
  bool    rs_inited;    /* false = scan not init'd yet */
70
  OffsetNumber rs_coffset;  /* current offset # in non-page-at-a-time mode */
71
  BlockNumber rs_cblock;    /* current block # in scan, if any */
72
  Buffer    rs_cbuf;    /* current buffer in scan, if any */
73
  /* NB: if rs_cbuf is not InvalidBuffer, we hold a pin on that buffer */
74
75
  BufferAccessStrategy rs_strategy; /* access strategy for reads */
76
77
  HeapTupleData rs_ctup;    /* current tuple in scan, if any */
78
79
  /* For scans that stream reads */
80
  ReadStream *rs_read_stream;
81
82
  /*
83
   * For sequential scans and TID range scans to stream reads. The read
84
   * stream is allocated at the beginning of the scan and reset on rescan or
85
   * when the scan direction changes. The scan direction is saved each time
86
   * a new page is requested. If the scan direction changes from one page to
87
   * the next, the read stream releases all previously pinned buffers and
88
   * resets the prefetch block.
89
   */
90
  ScanDirection rs_dir;
91
  BlockNumber rs_prefetch_block;
92
93
  /*
94
   * For parallel scans to store page allocation data.  NULL when not
95
   * performing a parallel scan.
96
   */
97
  ParallelBlockTableScanWorkerData *rs_parallelworkerdata;
98
99
  /* Current heap block's corresponding page in the visibility map */
100
  Buffer    rs_vmbuffer;
101
102
  /* these fields only used in page-at-a-time mode and for bitmap scans */
103
  uint32    rs_cindex;    /* current tuple's index in vistuples */
104
  uint32    rs_ntuples;   /* number of visible tuples on page */
105
  OffsetNumber rs_vistuples[MaxHeapTuplesPerPage];  /* their offsets */
106
} HeapScanDescData;
107
typedef struct HeapScanDescData *HeapScanDesc;
108
109
typedef struct BitmapHeapScanDescData
110
{
111
  HeapScanDescData rs_heap_base;
112
113
  /* Holds no data */
114
} BitmapHeapScanDescData;
115
typedef struct BitmapHeapScanDescData *BitmapHeapScanDesc;
116
117
/*
118
 * Descriptor for fetches from heap via an index.
119
 */
120
typedef struct IndexFetchHeapData
121
{
122
  IndexFetchTableData xs_base;  /* AM independent part of the descriptor */
123
124
  /*
125
   * Current heap buffer in scan (and its block number), if any.  NB: if
126
   * xs_blk is not InvalidBlockNumber, we hold a pin in xs_cbuf.
127
   */
128
  Buffer    xs_cbuf;
129
  BlockNumber xs_blk;
130
131
  /* Current heap block's corresponding page in the visibility map */
132
  Buffer    xs_vmbuffer;
133
} IndexFetchHeapData;
134
135
/* Result codes for HeapTupleSatisfiesVacuum */
136
typedef enum
137
{
138
  HEAPTUPLE_DEAD,       /* tuple is dead and deletable */
139
  HEAPTUPLE_LIVE,       /* tuple is live (committed, no deleter) */
140
  HEAPTUPLE_RECENTLY_DEAD,  /* tuple is dead, but not deletable yet */
141
  HEAPTUPLE_INSERT_IN_PROGRESS, /* inserting xact is still in progress */
142
  HEAPTUPLE_DELETE_IN_PROGRESS, /* deleting xact is still in progress */
143
} HTSV_Result;
144
145
/*
146
 * heap_prepare_freeze_tuple may request that heap_freeze_execute_prepared
147
 * check any tuple's to-be-frozen xmin and/or xmax status using pg_xact
148
 */
149
0
#define   HEAP_FREEZE_CHECK_XMIN_COMMITTED  0x01
150
0
#define   HEAP_FREEZE_CHECK_XMAX_ABORTED    0x02
151
152
/* heap_prepare_freeze_tuple state describing how to freeze a tuple */
153
typedef struct HeapTupleFreeze
154
{
155
  /* Fields describing how to process tuple */
156
  TransactionId xmax;
157
  uint16    t_infomask2;
158
  uint16    t_infomask;
159
  uint8   frzflags;
160
161
  /* xmin/xmax check flags */
162
  uint8   checkflags;
163
  /* Page offset number for tuple */
164
  OffsetNumber offset;
165
} HeapTupleFreeze;
166
167
/*
168
 * State used by VACUUM to track the details of freezing all eligible tuples
169
 * on a given heap page.
170
 *
171
 * VACUUM prepares freeze plans for each page via heap_prepare_freeze_tuple
172
 * calls (every tuple with storage gets its own call).  This page-level freeze
173
 * state is updated across each call, which ultimately determines whether or
174
 * not freezing the page is required.
175
 *
176
 * Aside from the basic question of whether or not freezing will go ahead, the
177
 * state also tracks the oldest extant XID/MXID in the table as a whole, for
178
 * the purposes of advancing relfrozenxid/relminmxid values in pg_class later
179
 * on.  Each heap_prepare_freeze_tuple call pushes NewRelfrozenXid and/or
180
 * NewRelminMxid back as required to avoid unsafe final pg_class values.  Any
181
 * and all unfrozen XIDs or MXIDs that remain after VACUUM finishes _must_
182
 * have values >= the final relfrozenxid/relminmxid values in pg_class.  This
183
 * includes XIDs that remain as MultiXact members from any tuple's xmax.
184
 *
185
 * When 'freeze_required' flag isn't set after all tuples are examined, the
186
 * final choice on freezing is made by vacuumlazy.c.  It can decide to trigger
187
 * freezing based on whatever criteria it deems appropriate.  However, it is
188
 * recommended that vacuumlazy.c avoid early freezing when freezing does not
189
 * enable setting the target page all-frozen in the visibility map afterwards.
190
 */
191
typedef struct HeapPageFreeze
192
{
193
  /* Is heap_prepare_freeze_tuple caller required to freeze page? */
194
  bool    freeze_required;
195
196
  /*
197
   * "Freeze" NewRelfrozenXid/NewRelminMxid trackers.
198
   *
199
   * Trackers used when heap_freeze_execute_prepared freezes, or when there
200
   * are zero freeze plans for a page.  It is always valid for vacuumlazy.c
201
   * to freeze any page, by definition.  This even includes pages that have
202
   * no tuples with storage to consider in the first place.  That way the
203
   * 'totally_frozen' results from heap_prepare_freeze_tuple can always be
204
   * used in the same way, even when no freeze plans need to be executed to
205
   * "freeze the page".  Only the "freeze" path needs to consider the need
206
   * to set pages all-frozen in the visibility map under this scheme.
207
   *
208
   * When we freeze a page, we generally freeze all XIDs < OldestXmin, only
209
   * leaving behind XIDs that are ineligible for freezing, if any.  And so
210
   * you might wonder why these trackers are necessary at all; why should
211
   * _any_ page that VACUUM freezes _ever_ be left with XIDs/MXIDs that
212
   * ratchet back the top-level NewRelfrozenXid/NewRelminMxid trackers?
213
   *
214
   * It is useful to use a definition of "freeze the page" that does not
215
   * overspecify how MultiXacts are affected.  heap_prepare_freeze_tuple
216
   * generally prefers to remove Multis eagerly, but lazy processing is used
217
   * in cases where laziness allows VACUUM to avoid allocating a new Multi.
218
   * The "freeze the page" trackers enable this flexibility.
219
   */
220
  TransactionId FreezePageRelfrozenXid;
221
  MultiXactId FreezePageRelminMxid;
222
223
  /*
224
   * Newest XID that this page's freeze actions will remove from tuple
225
   * visibility metadata (currently xmin and/or xvac). It is used to derive
226
   * the snapshot conflict horizon for a WAL record that freezes tuples. On
227
   * a standby, we must not replay that change while any snapshot could
228
   * still treat that XID as running.
229
   *
230
   * It's only used if we execute freeze plans for this page, so there is no
231
   * corresponding "no freeze" tracker.
232
   */
233
  TransactionId FreezePageConflictXid;
234
235
  /*
236
   * "No freeze" NewRelfrozenXid/NewRelminMxid trackers.
237
   *
238
   * These trackers are maintained in the same way as the trackers used when
239
   * VACUUM scans a page that isn't cleanup locked.  Both code paths are
240
   * based on the same general idea (do less work for this page during the
241
   * ongoing VACUUM, at the cost of having to accept older final values).
242
   */
243
  TransactionId NoFreezePageRelfrozenXid;
244
  MultiXactId NoFreezePageRelminMxid;
245
246
} HeapPageFreeze;
247
248
249
/* 'reason' codes for heap_page_prune_and_freeze() */
250
typedef enum
251
{
252
  PRUNE_ON_ACCESS,      /* on-access pruning */
253
  PRUNE_VACUUM_SCAN,      /* VACUUM 1st heap pass */
254
  PRUNE_VACUUM_CLEANUP,   /* VACUUM 2nd heap pass */
255
} PruneReason;
256
257
/*
258
 * Input parameters to heap_page_prune_and_freeze()
259
 */
260
typedef struct PruneFreezeParams
261
{
262
  Relation  relation;   /* relation containing buffer to be pruned */
263
  Buffer    buffer;     /* buffer to be pruned */
264
265
  /*
266
   * Callers should provide a pinned vmbuffer corresponding to the heap
267
   * block in buffer. We will check for and repair any corruption in the VM
268
   * and set the VM after pruning if the page is all-visible/all-frozen.
269
   */
270
  Buffer    vmbuffer;
271
272
  /*
273
   * The reason pruning was performed.  It is used to set the WAL record
274
   * opcode which is used for debugging and analysis purposes.
275
   */
276
  PruneReason reason;
277
278
  /*
279
   * Contains flag bits:
280
   *
281
   * HEAP_PAGE_PRUNE_MARK_UNUSED_NOW indicates that dead items can be set
282
   * LP_UNUSED during pruning.
283
   *
284
   * HEAP_PAGE_PRUNE_FREEZE indicates that we will also freeze tuples.
285
   */
286
  int     options;
287
288
  /*
289
   * vistest is used to distinguish whether tuples are DEAD or RECENTLY_DEAD
290
   * (see heap_prune_satisfies_vacuum).
291
   */
292
  GlobalVisState *vistest;
293
294
  /*
295
   * Contains the cutoffs used for freezing. They are required if the
296
   * HEAP_PAGE_PRUNE_FREEZE option is set. cutoffs->OldestXmin is also used
297
   * to determine if dead tuples are HEAPTUPLE_RECENTLY_DEAD or
298
   * HEAPTUPLE_DEAD. Currently only vacuum passes in cutoffs. Vacuum
299
   * calculates them once, at the beginning of vacuuming the relation.
300
   */
301
  VacuumCutoffs *cutoffs;
302
} PruneFreezeParams;
303
304
/*
305
 * Per-page state returned by heap_page_prune_and_freeze()
306
 */
307
typedef struct PruneFreezeResult
308
{
309
  int     ndeleted;   /* Number of tuples deleted from the page */
310
  int     nnewlpdead;   /* Number of newly LP_DEAD items */
311
  int     nfrozen;    /* Number of tuples we froze */
312
313
  /* Number of live and recently dead tuples on the page, after pruning */
314
  int     live_tuples;
315
  int     recently_dead_tuples;
316
317
  /*
318
   * Whether or not the page was newly set all-visible and all-frozen during
319
   * phase I of vacuuming.
320
   */
321
  bool    newly_all_visible;
322
  bool    newly_all_visible_frozen;
323
  bool    newly_all_frozen;
324
325
  /*
326
   * Whether or not the page makes rel truncation unsafe.  This is set to
327
   * 'true', even if the page contains LP_DEAD items.  VACUUM will remove
328
   * them before attempting to truncate.
329
   */
330
  bool    hastup;
331
332
  /*
333
   * LP_DEAD items on the page after pruning.  Includes existing LP_DEAD
334
   * items.
335
   */
336
  int     lpdead_items;
337
  OffsetNumber deadoffsets[MaxHeapTuplesPerPage];
338
} PruneFreezeResult;
339
340
341
/* ----------------
342
 *    function prototypes for heap access method
343
 *
344
 * heap_create, heap_create_with_catalog, and heap_drop_with_catalog
345
 * are declared in catalog/heap.h
346
 * ----------------
347
 */
348
349
350
extern TableScanDesc heap_beginscan(Relation relation, Snapshot snapshot,
351
                  int nkeys, ScanKey key,
352
                  ParallelTableScanDesc parallel_scan,
353
                  uint32 flags);
354
extern void heap_setscanlimits(TableScanDesc sscan, BlockNumber startBlk,
355
                 BlockNumber numBlks);
356
extern void heap_prepare_pagescan(TableScanDesc sscan);
357
extern void heap_rescan(TableScanDesc sscan, ScanKey key, bool set_params,
358
            bool allow_strat, bool allow_sync, bool allow_pagemode);
359
extern void heap_endscan(TableScanDesc sscan);
360
extern HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction);
361
extern bool heap_getnextslot(TableScanDesc sscan,
362
               ScanDirection direction, TupleTableSlot *slot);
363
extern void heap_set_tidrange(TableScanDesc sscan, ItemPointer mintid,
364
                ItemPointer maxtid);
365
extern bool heap_getnextslot_tidrange(TableScanDesc sscan,
366
                    ScanDirection direction,
367
                    TupleTableSlot *slot);
368
extern bool heap_fetch(Relation relation, Snapshot snapshot,
369
             HeapTuple tuple, Buffer *userbuf, bool keep_buf);
370
371
extern void heap_get_latest_tid(TableScanDesc sscan, ItemPointer tid);
372
373
extern BulkInsertState GetBulkInsertState(void);
374
extern void FreeBulkInsertState(BulkInsertState);
375
extern void ReleaseBulkInsertStatePin(BulkInsertState bistate);
376
377
extern void heap_insert(Relation relation, HeapTuple tup, CommandId cid,
378
            uint32 options, BulkInsertState bistate);
379
extern void heap_multi_insert(Relation relation, TupleTableSlot **slots,
380
                int ntuples, CommandId cid, uint32 options,
381
                BulkInsertState bistate);
382
extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid,
383
               CommandId cid, uint32 options, Snapshot crosscheck,
384
               bool wait, TM_FailureData *tmfd);
385
extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid);
386
extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid);
387
extern TM_Result heap_update(Relation relation, const ItemPointerData *otid,
388
               HeapTuple newtup,
389
               CommandId cid, uint32 options,
390
               Snapshot crosscheck, bool wait,
391
               TM_FailureData *tmfd, LockTupleMode *lockmode,
392
               TU_UpdateIndexes *update_indexes);
393
extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple,
394
                 CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy,
395
                 bool follow_updates,
396
                 Buffer *buffer, TM_FailureData *tmfd);
397
398
extern bool heap_inplace_lock(Relation relation,
399
                HeapTuple oldtup_ptr, Buffer buffer,
400
                void (*release_callback) (void *), void *arg);
401
extern void heap_inplace_update_and_unlock(Relation relation,
402
                       HeapTuple oldtup, HeapTuple tuple,
403
                       Buffer buffer);
404
extern void heap_inplace_unlock(Relation relation,
405
                HeapTuple oldtup, Buffer buffer);
406
extern bool heap_prepare_freeze_tuple(HeapTupleHeader tuple,
407
                    const VacuumCutoffs *cutoffs,
408
                    HeapPageFreeze *pagefrz,
409
                    HeapTupleFreeze *frz, bool *totally_frozen);
410
411
extern void heap_pre_freeze_checks(Buffer buffer,
412
                   HeapTupleFreeze *tuples, int ntuples);
413
extern void heap_freeze_prepared_tuples(Buffer buffer,
414
                    HeapTupleFreeze *tuples, int ntuples);
415
extern bool heap_freeze_tuple(HeapTupleHeader tuple,
416
                TransactionId relfrozenxid, TransactionId relminmxid,
417
                TransactionId FreezeLimit, TransactionId MultiXactCutoff);
418
extern bool heap_tuple_should_freeze(HeapTupleHeader tuple,
419
                   const VacuumCutoffs *cutoffs,
420
                   TransactionId *NoFreezePageRelfrozenXid,
421
                   MultiXactId *NoFreezePageRelminMxid);
422
extern bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple);
423
424
extern void simple_heap_insert(Relation relation, HeapTuple tup);
425
extern void simple_heap_delete(Relation relation, const ItemPointerData *tid);
426
extern void simple_heap_update(Relation relation, const ItemPointerData *otid,
427
                 HeapTuple tup, TU_UpdateIndexes *update_indexes);
428
429
extern TransactionId heap_index_delete_tuples(Relation rel,
430
                        TM_IndexDeleteOp *delstate);
431
432
/* in heap/heapam_indexscan.c */
433
extern IndexFetchTableData *heapam_index_fetch_begin(Relation rel, uint32 flags);
434
extern void heapam_index_fetch_reset(IndexFetchTableData *scan);
435
extern void heapam_index_fetch_end(IndexFetchTableData *scan);
436
extern bool heap_hot_search_buffer(ItemPointer tid, Relation relation,
437
                   Buffer buffer, Snapshot snapshot, HeapTuple heapTuple,
438
                   bool *all_dead, bool first_call);
439
extern bool heapam_index_fetch_tuple(struct IndexFetchTableData *scan,
440
                   ItemPointer tid, Snapshot snapshot,
441
                   TupleTableSlot *slot, bool *heap_continue,
442
                   bool *all_dead);
443
444
/* in heap/pruneheap.c */
445
extern void heap_page_prune_opt(Relation relation, Buffer buffer,
446
                Buffer *vmbuffer, bool rel_read_only);
447
extern void heap_page_prune_and_freeze(PruneFreezeParams *params,
448
                     PruneFreezeResult *presult,
449
                     OffsetNumber *off_loc,
450
                     TransactionId *new_relfrozen_xid,
451
                     MultiXactId *new_relmin_mxid);
452
extern void heap_page_prune_execute(Buffer buffer, bool lp_truncate_only,
453
                  OffsetNumber *redirected, int nredirected,
454
                  OffsetNumber *nowdead, int ndead,
455
                  OffsetNumber *nowunused, int nunused);
456
extern void heap_get_root_tuples(Page page, OffsetNumber *root_offsets);
457
extern void log_heap_prune_and_freeze(Relation relation, Buffer buffer,
458
                    Buffer vmbuffer, uint8 vmflags,
459
                    TransactionId conflict_xid,
460
                    bool cleanup_lock,
461
                    PruneReason reason,
462
                    HeapTupleFreeze *frozen, int nfrozen,
463
                    OffsetNumber *redirected, int nredirected,
464
                    OffsetNumber *dead, int ndead,
465
                    OffsetNumber *unused, int nunused);
466
467
/* in heap/vacuumlazy.c */
468
extern void heap_vacuum_rel(Relation rel,
469
              const VacuumParams *params, BufferAccessStrategy bstrategy);
470
#ifdef USE_ASSERT_CHECKING
471
extern bool heap_page_is_all_visible(Relation rel, Buffer buf,
472
                   GlobalVisState *vistest,
473
                   bool *all_frozen,
474
                   TransactionId *newest_live_xid,
475
                   OffsetNumber *logging_offnum);
476
#endif
477
478
/* in heap/heapam_visibility.c */
479
extern bool HeapTupleSatisfiesVisibility(HeapTuple htup, Snapshot snapshot,
480
                     Buffer buffer);
481
extern TM_Result HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
482
                      Buffer buffer);
483
extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin,
484
                      Buffer buffer);
485
extern HTSV_Result HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer,
486
                           TransactionId *dead_after);
487
extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
488
                 uint16 infomask, TransactionId xid);
489
extern bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple);
490
extern bool HeapTupleIsSurelyDead(HeapTuple htup,
491
                  GlobalVisState *vistest);
492
493
/*
494
 * Some of the input/output to/from HeapTupleSatisfiesMVCCBatch() is passed
495
 * via this struct, as otherwise the increased number of arguments to
496
 * HeapTupleSatisfiesMVCCBatch() leads to on-stack argument passing on x86-64,
497
 * which causes a small regression.
498
 */
499
typedef struct BatchMVCCState
500
{
501
  HeapTupleData tuples[MaxHeapTuplesPerPage];
502
  bool    visible[MaxHeapTuplesPerPage];
503
} BatchMVCCState;
504
505
extern int  HeapTupleSatisfiesMVCCBatch(Snapshot snapshot, Buffer buffer,
506
                    int ntups,
507
                    BatchMVCCState *batchmvcc,
508
                    OffsetNumber *vistuples_dense);
509
510
/*
511
 * To avoid leaking too much knowledge about reorderbuffer implementation
512
 * details this is implemented in reorderbuffer.c not heapam_visibility.c
513
 */
514
struct HTAB;
515
extern bool ResolveCminCmaxDuringDecoding(struct HTAB *tuplecid_data,
516
                      Snapshot snapshot,
517
                      HeapTuple htup,
518
                      Buffer buffer,
519
                      CommandId *cmin, CommandId *cmax);
520
extern void HeapCheckForSerializableConflictOut(bool visible, Relation relation, HeapTuple tuple,
521
                        Buffer buffer, Snapshot snapshot);
522
523
/*
524
 * heap_execute_freeze_tuple
525
 *    Execute the prepared freezing of a tuple with caller's freeze plan.
526
 *
527
 * Caller is responsible for ensuring that no other backend can access the
528
 * storage underlying this tuple, either by holding an exclusive lock on the
529
 * buffer containing it (which is what lazy VACUUM does), or by having it be
530
 * in private storage (which is what CLUSTER and friends do).
531
 */
532
static inline void
533
heap_execute_freeze_tuple(HeapTupleHeader tuple, HeapTupleFreeze *frz)
534
0
{
535
0
  HeapTupleHeaderSetXmax(tuple, frz->xmax);
536
537
0
  if (frz->frzflags & XLH_FREEZE_XVAC)
538
0
    HeapTupleHeaderSetXvac(tuple, FrozenTransactionId);
539
540
0
  if (frz->frzflags & XLH_INVALID_XVAC)
541
0
    HeapTupleHeaderSetXvac(tuple, InvalidTransactionId);
542
543
0
  tuple->t_infomask = frz->t_infomask;
544
0
  tuple->t_infomask2 = frz->t_infomask2;
545
0
}
Unexecuted instantiation: toast_internals.c:heap_execute_freeze_tuple
Unexecuted instantiation: heapam.c:heap_execute_freeze_tuple
Unexecuted instantiation: heapam_handler.c:heap_execute_freeze_tuple
Unexecuted instantiation: heapam_indexscan.c:heap_execute_freeze_tuple
Unexecuted instantiation: heapam_visibility.c:heap_execute_freeze_tuple
Unexecuted instantiation: heapam_xlog.c:heap_execute_freeze_tuple
Unexecuted instantiation: heaptoast.c:heap_execute_freeze_tuple
Unexecuted instantiation: hio.c:heap_execute_freeze_tuple
Unexecuted instantiation: pruneheap.c:heap_execute_freeze_tuple
Unexecuted instantiation: rewriteheap.c:heap_execute_freeze_tuple
Unexecuted instantiation: vacuumlazy.c:heap_execute_freeze_tuple
Unexecuted instantiation: genam.c:heap_execute_freeze_tuple
Unexecuted instantiation: bootstrap.c:heap_execute_freeze_tuple
Unexecuted instantiation: aclchk.c:heap_execute_freeze_tuple
Unexecuted instantiation: index.c:heap_execute_freeze_tuple
Unexecuted instantiation: indexing.c:heap_execute_freeze_tuple
Unexecuted instantiation: pg_db_role_setting.c:heap_execute_freeze_tuple
Unexecuted instantiation: pg_publication.c:heap_execute_freeze_tuple
Unexecuted instantiation: pg_subscription.c:heap_execute_freeze_tuple
Unexecuted instantiation: toasting.c:heap_execute_freeze_tuple
Unexecuted instantiation: copyfrom.c:heap_execute_freeze_tuple
Unexecuted instantiation: createas.c:heap_execute_freeze_tuple
Unexecuted instantiation: dbcommands.c:heap_execute_freeze_tuple
Unexecuted instantiation: event_trigger.c:heap_execute_freeze_tuple
Unexecuted instantiation: indexcmds.c:heap_execute_freeze_tuple
Unexecuted instantiation: matview.c:heap_execute_freeze_tuple
Unexecuted instantiation: repack.c:heap_execute_freeze_tuple
Unexecuted instantiation: tablecmds.c:heap_execute_freeze_tuple
Unexecuted instantiation: tablespace.c:heap_execute_freeze_tuple
Unexecuted instantiation: vacuum.c:heap_execute_freeze_tuple
Unexecuted instantiation: execReplication.c:heap_execute_freeze_tuple
Unexecuted instantiation: autovacuum.c:heap_execute_freeze_tuple
Unexecuted instantiation: datachecksum_state.c:heap_execute_freeze_tuple
Unexecuted instantiation: launcher.c:heap_execute_freeze_tuple
Unexecuted instantiation: reorderbuffer.c:heap_execute_freeze_tuple
Unexecuted instantiation: attribute_stats.c:heap_execute_freeze_tuple
Unexecuted instantiation: extended_stats_funcs.c:heap_execute_freeze_tuple
Unexecuted instantiation: relation_stats.c:heap_execute_freeze_tuple
Unexecuted instantiation: postinit.c:heap_execute_freeze_tuple
546
547
#endif              /* HEAPAM_H */