Coverage Report

Created: 2026-11-12 07:20

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
 * heapam-specific IndexScanDescData opaque state
119
 */
120
typedef struct IndexScanHeapData
121
{
122
  /*
123
   * Current heap buffer in scan (and its block number), if any.  NB: if
124
   * xs_blk is not InvalidBlockNumber, we hold a pin in xs_cbuf.
125
   */
126
  Buffer    xs_cbuf;
127
  BlockNumber xs_blk;
128
129
  Buffer    xs_vmbuffer;  /* visibility map buffer */
130
131
  bool    xs_readonly;  /* scan is read-only? */
132
133
  uint16    xs_blkswitch_count; /* number of heap blocks fetched */
134
} IndexScanHeapData;
135
136
/* Result codes for HeapTupleSatisfiesVacuum */
137
typedef enum
138
{
139
  HEAPTUPLE_DEAD,       /* tuple is dead and deletable */
140
  HEAPTUPLE_LIVE,       /* tuple is live (committed, no deleter) */
141
  HEAPTUPLE_RECENTLY_DEAD,  /* tuple is dead, but not deletable yet */
142
  HEAPTUPLE_INSERT_IN_PROGRESS, /* inserting xact is still in progress */
143
  HEAPTUPLE_DELETE_IN_PROGRESS, /* deleting xact is still in progress */
144
} HTSV_Result;
145
146
/*
147
 * heap_prepare_freeze_tuple may request that heap_freeze_execute_prepared
148
 * check any tuple's to-be-frozen xmin and/or xmax status using pg_xact
149
 */
150
0
#define   HEAP_FREEZE_CHECK_XMIN_COMMITTED  0x01
151
0
#define   HEAP_FREEZE_CHECK_XMAX_ABORTED    0x02
152
153
/* heap_prepare_freeze_tuple state describing how to freeze a tuple */
154
typedef struct HeapTupleFreeze
155
{
156
  /* Fields describing how to process tuple */
157
  TransactionId xmax;
158
  uint16    t_infomask2;
159
  uint16    t_infomask;
160
  uint8   frzflags;
161
162
  /* xmin/xmax check flags */
163
  uint8   checkflags;
164
  /* Page offset number for tuple */
165
  OffsetNumber offset;
166
} HeapTupleFreeze;
167
168
/*
169
 * State used by VACUUM to track the details of freezing all eligible tuples
170
 * on a given heap page.
171
 *
172
 * VACUUM prepares freeze plans for each page via heap_prepare_freeze_tuple
173
 * calls (every tuple with storage gets its own call).  This page-level freeze
174
 * state is updated across each call, which ultimately determines whether or
175
 * not freezing the page is required.
176
 *
177
 * Aside from the basic question of whether or not freezing will go ahead, the
178
 * state also tracks the oldest extant XID/MXID in the table as a whole, for
179
 * the purposes of advancing relfrozenxid/relminmxid values in pg_class later
180
 * on.  Each heap_prepare_freeze_tuple call pushes NewRelfrozenXid and/or
181
 * NewRelminMxid back as required to avoid unsafe final pg_class values.  Any
182
 * and all unfrozen XIDs or MXIDs that remain after VACUUM finishes _must_
183
 * have values >= the final relfrozenxid/relminmxid values in pg_class.  This
184
 * includes XIDs that remain as MultiXact members from any tuple's xmax.
185
 *
186
 * When 'freeze_required' flag isn't set after all tuples are examined, the
187
 * final choice on freezing is made by vacuumlazy.c.  It can decide to trigger
188
 * freezing based on whatever criteria it deems appropriate.  However, it is
189
 * recommended that vacuumlazy.c avoid early freezing when freezing does not
190
 * enable setting the target page all-frozen in the visibility map afterwards.
191
 */
192
typedef struct HeapPageFreeze
193
{
194
  /* Is heap_prepare_freeze_tuple caller required to freeze page? */
195
  bool    freeze_required;
196
197
  /*
198
   * "Freeze" NewRelfrozenXid/NewRelminMxid trackers.
199
   *
200
   * Trackers used when heap_freeze_execute_prepared freezes, or when there
201
   * are zero freeze plans for a page.  It is always valid for vacuumlazy.c
202
   * to freeze any page, by definition.  This even includes pages that have
203
   * no tuples with storage to consider in the first place.  That way the
204
   * 'totally_frozen' results from heap_prepare_freeze_tuple can always be
205
   * used in the same way, even when no freeze plans need to be executed to
206
   * "freeze the page".  Only the "freeze" path needs to consider the need
207
   * to set pages all-frozen in the visibility map under this scheme.
208
   *
209
   * When we freeze a page, we generally freeze all XIDs < OldestXmin, only
210
   * leaving behind XIDs that are ineligible for freezing, if any.  And so
211
   * you might wonder why these trackers are necessary at all; why should
212
   * _any_ page that VACUUM freezes _ever_ be left with XIDs/MXIDs that
213
   * ratchet back the top-level NewRelfrozenXid/NewRelminMxid trackers?
214
   *
215
   * It is useful to use a definition of "freeze the page" that does not
216
   * overspecify how MultiXacts are affected.  heap_prepare_freeze_tuple
217
   * generally prefers to remove Multis eagerly, but lazy processing is used
218
   * in cases where laziness allows VACUUM to avoid allocating a new Multi.
219
   * The "freeze the page" trackers enable this flexibility.
220
   */
221
  TransactionId FreezePageRelfrozenXid;
222
  MultiXactId FreezePageRelminMxid;
223
224
  /*
225
   * Newest XID that this page's freeze actions will remove from tuple
226
   * visibility metadata (currently xmin and/or xvac). It is used to derive
227
   * the snapshot conflict horizon for a WAL record that freezes tuples. On
228
   * a standby, we must not replay that change while any snapshot could
229
   * still treat that XID as running.
230
   *
231
   * It's only used if we execute freeze plans for this page, so there is no
232
   * corresponding "no freeze" tracker.
233
   */
234
  TransactionId FreezePageConflictXid;
235
236
  /*
237
   * "No freeze" NewRelfrozenXid/NewRelminMxid trackers.
238
   *
239
   * These trackers are maintained in the same way as the trackers used when
240
   * VACUUM scans a page that isn't cleanup locked.  Both code paths are
241
   * based on the same general idea (do less work for this page during the
242
   * ongoing VACUUM, at the cost of having to accept older final values).
243
   */
244
  TransactionId NoFreezePageRelfrozenXid;
245
  MultiXactId NoFreezePageRelminMxid;
246
247
} HeapPageFreeze;
248
249
250
/* 'reason' codes for heap_page_prune_and_freeze() */
251
typedef enum
252
{
253
  PRUNE_ON_ACCESS,      /* on-access pruning */
254
  PRUNE_VACUUM_SCAN,      /* VACUUM 1st heap pass */
255
  PRUNE_VACUUM_CLEANUP,   /* VACUUM 2nd heap pass */
256
} PruneReason;
257
258
/*
259
 * Input parameters to heap_page_prune_and_freeze()
260
 */
261
typedef struct PruneFreezeParams
262
{
263
  Relation  relation;   /* relation containing buffer to be pruned */
264
  Buffer    buffer;     /* buffer to be pruned */
265
266
  /*
267
   * Callers should provide a pinned vmbuffer corresponding to the heap
268
   * block in buffer. We will check for and repair any corruption in the VM
269
   * and set the VM after pruning if the page is all-visible/all-frozen.
270
   */
271
  Buffer    vmbuffer;
272
273
  /*
274
   * The reason pruning was performed.  It is used to set the WAL record
275
   * opcode which is used for debugging and analysis purposes.
276
   */
277
  PruneReason reason;
278
279
  /*
280
   * Contains flag bits:
281
   *
282
   * HEAP_PAGE_PRUNE_MARK_UNUSED_NOW indicates that dead items can be set
283
   * LP_UNUSED during pruning.
284
   *
285
   * HEAP_PAGE_PRUNE_FREEZE indicates that we will also freeze tuples.
286
   */
287
  int     options;
288
289
  /*
290
   * vistest is used to distinguish whether tuples are DEAD or RECENTLY_DEAD
291
   * (see heap_prune_satisfies_vacuum).
292
   */
293
  GlobalVisState *vistest;
294
295
  /*
296
   * Contains the cutoffs used for freezing. They are required if the
297
   * HEAP_PAGE_PRUNE_FREEZE option is set. cutoffs->OldestXmin is also used
298
   * to determine if dead tuples are HEAPTUPLE_RECENTLY_DEAD or
299
   * HEAPTUPLE_DEAD. Currently only vacuum passes in cutoffs. Vacuum
300
   * calculates them once, at the beginning of vacuuming the relation.
301
   */
302
  VacuumCutoffs *cutoffs;
303
} PruneFreezeParams;
304
305
/*
306
 * Per-page state returned by heap_page_prune_and_freeze()
307
 */
308
typedef struct PruneFreezeResult
309
{
310
  int     ndeleted;   /* Number of tuples deleted from the page */
311
  int     nnewlpdead;   /* Number of newly LP_DEAD items */
312
  int     nfrozen;    /* Number of tuples we froze */
313
314
  /* Number of live and recently dead tuples on the page, after pruning */
315
  int     live_tuples;
316
  int     recently_dead_tuples;
317
318
  /*
319
   * Whether or not the page was newly set all-visible and all-frozen during
320
   * phase I of vacuuming.
321
   */
322
  bool    newly_all_visible;
323
  bool    newly_all_visible_frozen;
324
  bool    newly_all_frozen;
325
326
  /*
327
   * Whether or not the page makes rel truncation unsafe.  This is set to
328
   * 'true', even if the page contains LP_DEAD items.  VACUUM will remove
329
   * them before attempting to truncate.
330
   */
331
  bool    hastup;
332
333
  /*
334
   * LP_DEAD items on the page after pruning.  Includes existing LP_DEAD
335
   * items.
336
   */
337
  int     lpdead_items;
338
  OffsetNumber deadoffsets[MaxHeapTuplesPerPage];
339
} PruneFreezeResult;
340
341
342
/* ----------------
343
 *    function prototypes for heap access method
344
 *
345
 * heap_create, heap_create_with_catalog, and heap_drop_with_catalog
346
 * are declared in catalog/heap.h
347
 * ----------------
348
 */
349
350
351
extern TableScanDesc heap_beginscan(Relation relation, Snapshot snapshot,
352
                  int nkeys, ScanKey key,
353
                  ParallelTableScanDesc parallel_scan,
354
                  uint32 flags);
355
extern void heap_setscanlimits(TableScanDesc sscan, BlockNumber startBlk,
356
                 BlockNumber numBlks);
357
extern void heap_prepare_pagescan(TableScanDesc sscan);
358
extern void heap_rescan(TableScanDesc sscan, ScanKey key, bool set_params,
359
            bool allow_strat, bool allow_sync, bool allow_pagemode);
360
extern void heap_endscan(TableScanDesc sscan);
361
extern HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction);
362
extern bool heap_getnextslot(TableScanDesc sscan,
363
               ScanDirection direction, TupleTableSlot *slot);
364
extern void heap_set_tidrange(TableScanDesc sscan, ItemPointer mintid,
365
                ItemPointer maxtid);
366
extern bool heap_getnextslot_tidrange(TableScanDesc sscan,
367
                    ScanDirection direction,
368
                    TupleTableSlot *slot);
369
extern bool heap_fetch(Relation relation, Snapshot snapshot,
370
             HeapTuple tuple, Buffer *userbuf, bool keep_buf);
371
372
extern void heap_get_latest_tid(TableScanDesc sscan, ItemPointer tid);
373
374
extern BulkInsertState GetBulkInsertState(void);
375
extern void FreeBulkInsertState(BulkInsertState);
376
extern void ReleaseBulkInsertStatePin(BulkInsertState bistate);
377
378
extern void heap_insert(Relation relation, HeapTuple tup, CommandId cid,
379
            uint32 options, BulkInsertState bistate);
380
extern void heap_multi_insert(Relation relation, TupleTableSlot **slots,
381
                int ntuples, CommandId cid, uint32 options,
382
                BulkInsertState bistate);
383
extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid,
384
               CommandId cid, uint32 options, Snapshot crosscheck,
385
               bool wait, TM_FailureData *tmfd);
386
extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid);
387
extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid);
388
extern TM_Result heap_update(Relation relation, const ItemPointerData *otid,
389
               HeapTuple newtup,
390
               CommandId cid, uint32 options,
391
               Snapshot crosscheck, bool wait,
392
               TM_FailureData *tmfd, LockTupleMode *lockmode,
393
               TU_UpdateIndexes *update_indexes);
394
extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple,
395
                 CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy,
396
                 bool follow_updates,
397
                 Buffer *buffer, TM_FailureData *tmfd);
398
399
extern bool heap_inplace_lock(Relation relation,
400
                HeapTuple oldtup_ptr, Buffer buffer,
401
                void (*release_callback) (void *), void *arg);
402
extern void heap_inplace_update_and_unlock(Relation relation,
403
                       HeapTuple oldtup, HeapTuple tuple,
404
                       Buffer buffer);
405
extern void heap_inplace_unlock(Relation relation,
406
                HeapTuple oldtup, Buffer buffer);
407
extern bool heap_prepare_freeze_tuple(HeapTupleHeader tuple,
408
                    const VacuumCutoffs *cutoffs,
409
                    HeapPageFreeze *pagefrz,
410
                    HeapTupleFreeze *frz, bool *totally_frozen);
411
412
extern void heap_pre_freeze_checks(Buffer buffer,
413
                   HeapTupleFreeze *tuples, int ntuples);
414
extern void heap_freeze_prepared_tuples(Buffer buffer,
415
                    HeapTupleFreeze *tuples, int ntuples);
416
extern bool heap_freeze_tuple(HeapTupleHeader tuple,
417
                TransactionId relfrozenxid, TransactionId relminmxid,
418
                TransactionId FreezeLimit, TransactionId MultiXactCutoff);
419
extern bool heap_tuple_should_freeze(HeapTupleHeader tuple,
420
                   const VacuumCutoffs *cutoffs,
421
                   TransactionId *NoFreezePageRelfrozenXid,
422
                   MultiXactId *NoFreezePageRelminMxid);
423
extern bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple);
424
425
extern void simple_heap_insert(Relation relation, HeapTuple tup);
426
extern void simple_heap_delete(Relation relation, const ItemPointerData *tid);
427
extern void simple_heap_update(Relation relation, const ItemPointerData *otid,
428
                 HeapTuple tup, TU_UpdateIndexes *update_indexes);
429
430
extern TransactionId heap_index_delete_tuples(Relation rel,
431
                        TM_IndexDeleteOp *delstate);
432
433
/* in heap/heapam_indexscan.c */
434
extern bool heapam_fetch_tid(Relation rel, ItemPointer tid, Snapshot snapshot,
435
               bool *all_dead);
436
extern void heapam_index_scan_begin(IndexScanDesc scan, uint32 flags);
437
extern void heapam_index_scan_reset(IndexScanDesc scan);
438
extern void heapam_index_scan_end(IndexScanDesc scan);
439
extern bool heap_hot_search_buffer(ItemPointer tid, Relation relation,
440
                   Buffer buffer, Snapshot snapshot, HeapTuple heapTuple,
441
                   bool *all_dead, bool first_call);
442
443
/* in heap/pruneheap.c */
444
extern void heap_page_prune_opt(Relation relation, Buffer buffer,
445
                Buffer *vmbuffer, bool rel_read_only);
446
extern void heap_page_prune_and_freeze(PruneFreezeParams *params,
447
                     PruneFreezeResult *presult,
448
                     OffsetNumber *off_loc,
449
                     TransactionId *new_relfrozen_xid,
450
                     MultiXactId *new_relmin_mxid);
451
extern void heap_page_prune_execute(Buffer buffer, bool lp_truncate_only,
452
                  OffsetNumber *redirected, int nredirected,
453
                  OffsetNumber *nowdead, int ndead,
454
                  OffsetNumber *nowunused, int nunused);
455
extern void heap_get_root_tuples(Page page, OffsetNumber *root_offsets);
456
extern void log_heap_prune_and_freeze(Relation relation, Buffer buffer,
457
                    Buffer vmbuffer, uint8 vmflags,
458
                    TransactionId conflict_xid,
459
                    bool cleanup_lock,
460
                    PruneReason reason,
461
                    HeapTupleFreeze *frozen, int nfrozen,
462
                    OffsetNumber *redirected, int nredirected,
463
                    OffsetNumber *dead, int ndead,
464
                    OffsetNumber *unused, int nunused);
465
466
/* in heap/vacuumlazy.c */
467
extern void heap_vacuum_rel(Relation rel,
468
              const VacuumParams *params, BufferAccessStrategy bstrategy);
469
#ifdef USE_ASSERT_CHECKING
470
extern bool heap_page_is_all_visible(Relation rel, Buffer buf,
471
                   GlobalVisState *vistest,
472
                   bool *all_frozen,
473
                   TransactionId *newest_live_xid,
474
                   OffsetNumber *logging_offnum);
475
#endif
476
477
/* in heap/heapam_visibility.c */
478
extern bool HeapTupleSatisfiesVisibility(HeapTuple htup, Snapshot snapshot,
479
                     Buffer buffer);
480
extern TM_Result HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
481
                      Buffer buffer);
482
extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin,
483
                      Buffer buffer);
484
extern HTSV_Result HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer,
485
                           TransactionId *dead_after);
486
extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
487
                 uint16 infomask, TransactionId xid);
488
extern bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple);
489
extern bool HeapTupleIsSurelyDead(HeapTuple htup,
490
                  GlobalVisState *vistest);
491
492
/*
493
 * Some of the input/output to/from HeapTupleSatisfiesMVCCBatch() is passed
494
 * via this struct, as otherwise the increased number of arguments to
495
 * HeapTupleSatisfiesMVCCBatch() leads to on-stack argument passing on x86-64,
496
 * which causes a small regression.
497
 */
498
typedef struct BatchMVCCState
499
{
500
  HeapTupleData tuples[MaxHeapTuplesPerPage];
501
  bool    visible[MaxHeapTuplesPerPage];
502
} BatchMVCCState;
503
504
extern int  HeapTupleSatisfiesMVCCBatch(Snapshot snapshot, Buffer buffer,
505
                    int ntups,
506
                    BatchMVCCState *batchmvcc,
507
                    OffsetNumber *vistuples_dense);
508
509
/*
510
 * To avoid leaking too much knowledge about reorderbuffer implementation
511
 * details this is implemented in reorderbuffer.c not heapam_visibility.c
512
 */
513
struct HTAB;
514
extern bool ResolveCminCmaxDuringDecoding(struct HTAB *tuplecid_data,
515
                      Snapshot snapshot,
516
                      HeapTuple htup,
517
                      Buffer buffer,
518
                      CommandId *cmin, CommandId *cmax);
519
extern void HeapCheckForSerializableConflictOut(bool visible, Relation relation, HeapTuple tuple,
520
                        Buffer buffer, Snapshot snapshot);
521
522
/*
523
 * heap_execute_freeze_tuple
524
 *    Execute the prepared freezing of a tuple with caller's freeze plan.
525
 *
526
 * Caller is responsible for ensuring that no other backend can access the
527
 * storage underlying this tuple, either by holding an exclusive lock on the
528
 * buffer containing it (which is what lazy VACUUM does), or by having it be
529
 * in private storage (which is what CLUSTER and friends do).
530
 */
531
static inline void
532
heap_execute_freeze_tuple(HeapTupleHeader tuple, HeapTupleFreeze *frz)
533
0
{
534
0
  HeapTupleHeaderSetXmax(tuple, frz->xmax);
535
536
0
  if (frz->frzflags & XLH_FREEZE_XVAC)
537
0
    HeapTupleHeaderSetXvac(tuple, FrozenTransactionId);
538
539
0
  if (frz->frzflags & XLH_INVALID_XVAC)
540
0
    HeapTupleHeaderSetXvac(tuple, InvalidTransactionId);
541
542
0
  tuple->t_infomask = frz->t_infomask;
543
0
  tuple->t_infomask2 = frz->t_infomask2;
544
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
545
546
#endif              /* HEAPAM_H */