PostgreSQL Source Code git master
Loading...
Searching...
No Matches
tableam.h File Reference
#include "access/relscan.h"
#include "access/sdir.h"
#include "access/xact.h"
#include "executor/tuptable.h"
#include "storage/read_stream.h"
#include "utils/rel.h"
#include "utils/snapshot.h"
Include dependency graph for tableam.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  TM_FailureData
 
struct  TM_IndexDelete
 
struct  TM_IndexStatus
 
struct  TM_IndexDeleteOp
 
struct  TableAmRoutine
 

Macros

#define DEFAULT_TABLE_ACCESS_METHOD   "heap"
 
#define SO_INTERNAL_FLAGS
 
#define TABLE_INSERT_SKIP_FSM   0x0002
 
#define TABLE_INSERT_FROZEN   0x0004
 
#define TABLE_INSERT_NO_LOGICAL   0x0008
 
#define TABLE_DELETE_CHANGING_PARTITION   (1 << 0)
 
#define TABLE_DELETE_NO_LOGICAL   (1 << 1)
 
#define TABLE_UPDATE_NO_LOGICAL   (1 << 0)
 
#define TUPLE_LOCK_FLAG_LOCK_UPDATE_IN_PROGRESS   (1 << 0)
 
#define TUPLE_LOCK_FLAG_FIND_LAST_VERSION   (1 << 1)
 

Typedefs

typedef struct BulkInsertStateData BulkInsertStateData
 
typedef struct IndexInfo IndexInfo
 
typedef struct SampleScanState SampleScanState
 
typedef struct ScanKeyData ScanKeyData
 
typedef struct ValidateIndexState ValidateIndexState
 
typedef struct VacuumParams VacuumParams
 
typedef enum ScanOptions ScanOptions
 
typedef enum TM_Result TM_Result
 
typedef enum TU_UpdateIndexes TU_UpdateIndexes
 
typedef struct TM_FailureData TM_FailureData
 
typedef struct TM_IndexDelete TM_IndexDelete
 
typedef struct TM_IndexStatus TM_IndexStatus
 
typedef struct TM_IndexDeleteOp TM_IndexDeleteOp
 
typedef void(* IndexBuildCallback) (Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
 
typedef struct TableAmRoutine TableAmRoutine
 

Enumerations

enum  ScanOptions {
  SO_NONE = 0 , SO_TYPE_SEQSCAN = 1 << 0 , SO_TYPE_BITMAPSCAN = 1 << 1 , SO_TYPE_SAMPLESCAN = 1 << 2 ,
  SO_TYPE_TIDSCAN = 1 << 3 , SO_TYPE_TIDRANGESCAN = 1 << 4 , SO_TYPE_ANALYZE = 1 << 5 , SO_ALLOW_STRAT = 1 << 6 ,
  SO_ALLOW_SYNC = 1 << 7 , SO_ALLOW_PAGEMODE = 1 << 8 , SO_TEMP_SNAPSHOT = 1 << 9 , SO_HINT_REL_READ_ONLY = 1 << 10 ,
  SO_SCAN_INSTRUMENT = 1 << 11
}
 
enum  TM_Result {
  TM_Ok , TM_Invisible , TM_SelfModified , TM_Updated ,
  TM_Deleted , TM_BeingModified , TM_WouldBlock
}
 
enum  TU_UpdateIndexes { TU_None , TU_All , TU_Summarizing }
 

Functions

const TupleTableSlotOpstable_slot_callbacks (Relation relation)
 
TupleTableSlottable_slot_create (Relation relation, List **reglist)
 
static TableScanDesc table_beginscan_common (Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, ParallelTableScanDesc pscan, uint32 flags, uint32 user_flags)
 
static TableScanDesc table_beginscan (Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, uint32 flags)
 
TableScanDesc table_beginscan_catalog (Relation relation, int nkeys, ScanKeyData *key)
 
static TableScanDesc table_beginscan_strat (Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, bool allow_strat, bool allow_sync)
 
static TableScanDesc table_beginscan_bm (Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, uint32 flags)
 
static TableScanDesc table_beginscan_sampling (Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, bool allow_strat, bool allow_sync, bool allow_pagemode, uint32 flags)
 
static TableScanDesc table_beginscan_tid (Relation rel, Snapshot snapshot)
 
static TableScanDesc table_beginscan_analyze (Relation rel)
 
static void table_endscan (TableScanDesc scan)
 
static void table_rescan (TableScanDesc scan, ScanKeyData *key)
 
static void table_rescan_set_params (TableScanDesc scan, ScanKeyData *key, bool allow_strat, bool allow_sync, bool allow_pagemode)
 
static bool table_scan_getnextslot (TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
 
static TableScanDesc table_beginscan_tidrange (Relation rel, Snapshot snapshot, ItemPointer mintid, ItemPointer maxtid, uint32 flags)
 
static void table_rescan_tidrange (TableScanDesc sscan, ItemPointer mintid, ItemPointer maxtid)
 
static bool table_scan_getnextslot_tidrange (TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
 
Size table_parallelscan_estimate (Relation rel, Snapshot snapshot)
 
void table_parallelscan_initialize (Relation rel, ParallelTableScanDesc pscan, Snapshot snapshot)
 
TableScanDesc table_beginscan_parallel (Relation relation, ParallelTableScanDesc pscan, uint32 flags)
 
TableScanDesc table_beginscan_parallel_tidrange (Relation relation, ParallelTableScanDesc pscan, uint32 flags)
 
static void table_parallelscan_reinitialize (Relation rel, ParallelTableScanDesc pscan)
 
static IndexFetchTableDatatable_index_fetch_begin (Relation rel, uint32 flags)
 
static void table_index_fetch_reset (struct IndexFetchTableData *scan)
 
static void table_index_fetch_end (struct IndexFetchTableData *scan)
 
static bool table_index_fetch_tuple (struct IndexFetchTableData *scan, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot, bool *call_again, bool *all_dead)
 
bool table_index_fetch_tuple_check (Relation rel, ItemPointer tid, Snapshot snapshot, bool *all_dead)
 
static bool table_tuple_fetch_row_version (Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot)
 
static bool table_tuple_tid_valid (TableScanDesc scan, ItemPointer tid)
 
void table_tuple_get_latest_tid (TableScanDesc scan, ItemPointer tid)
 
static bool table_tuple_satisfies_snapshot (Relation rel, TupleTableSlot *slot, Snapshot snapshot)
 
static TransactionId table_index_delete_tuples (Relation rel, TM_IndexDeleteOp *delstate)
 
static void table_tuple_insert (Relation rel, TupleTableSlot *slot, CommandId cid, uint32 options, BulkInsertStateData *bistate)
 
static void table_tuple_insert_speculative (Relation rel, TupleTableSlot *slot, CommandId cid, uint32 options, BulkInsertStateData *bistate, uint32 specToken)
 
static void table_tuple_complete_speculative (Relation rel, TupleTableSlot *slot, uint32 specToken, bool succeeded)
 
static void table_multi_insert (Relation rel, TupleTableSlot **slots, int nslots, CommandId cid, uint32 options, BulkInsertStateData *bistate)
 
static TM_Result table_tuple_delete (Relation rel, ItemPointer tid, CommandId cid, uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd)
 
static TM_Result table_tuple_update (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes)
 
static TM_Result table_tuple_lock (Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot, CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy, uint8 flags, TM_FailureData *tmfd)
 
static void table_finish_bulk_insert (Relation rel, uint32 options)
 
static void table_relation_set_new_filelocator (Relation rel, const RelFileLocator *newrlocator, char persistence, TransactionId *freezeXid, MultiXactId *minmulti)
 
static void table_relation_nontransactional_truncate (Relation rel)
 
static void table_relation_copy_data (Relation rel, const RelFileLocator *newrlocator)
 
static void table_relation_copy_for_cluster (Relation OldTable, Relation NewTable, Relation OldIndex, bool use_sort, TransactionId OldestXmin, Snapshot snapshot, TransactionId *xid_cutoff, MultiXactId *multi_cutoff, double *num_tuples, double *tups_vacuumed, double *tups_recently_dead)
 
static void table_relation_vacuum (Relation rel, const VacuumParams *params, BufferAccessStrategy bstrategy)
 
static bool table_scan_analyze_next_block (TableScanDesc scan, ReadStream *stream)
 
static bool table_scan_analyze_next_tuple (TableScanDesc scan, double *liverows, double *deadrows, TupleTableSlot *slot)
 
static double table_index_build_scan (Relation table_rel, Relation index_rel, IndexInfo *index_info, bool allow_sync, bool progress, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)
 
static double table_index_build_range_scan (Relation table_rel, Relation index_rel, IndexInfo *index_info, bool allow_sync, bool anyvisible, bool progress, BlockNumber start_blockno, BlockNumber numblocks, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)
 
static void table_index_validate_scan (Relation table_rel, Relation index_rel, IndexInfo *index_info, Snapshot snapshot, ValidateIndexState *state)
 
static uint64 table_relation_size (Relation rel, ForkNumber forkNumber)
 
static bool table_relation_needs_toast_table (Relation rel)
 
static Oid table_relation_toast_am (Relation rel)
 
static void table_relation_fetch_toast_slice (Relation toastrel, Oid valueid, int32 attrsize, int32 sliceoffset, int32 slicelength, varlena *result)
 
static void table_relation_estimate_size (Relation rel, int32 *attr_widths, BlockNumber *pages, double *tuples, double *allvisfrac)
 
static bool table_scan_bitmap_next_tuple (TableScanDesc scan, TupleTableSlot *slot, bool *recheck, uint64 *lossy_pages, uint64 *exact_pages)
 
static bool table_scan_sample_next_block (TableScanDesc scan, SampleScanState *scanstate)
 
static bool table_scan_sample_next_tuple (TableScanDesc scan, SampleScanState *scanstate, TupleTableSlot *slot)
 
void simple_table_tuple_insert (Relation rel, TupleTableSlot *slot)
 
void simple_table_tuple_delete (Relation rel, ItemPointer tid, Snapshot snapshot)
 
void simple_table_tuple_update (Relation rel, ItemPointer otid, TupleTableSlot *slot, Snapshot snapshot, TU_UpdateIndexes *update_indexes)
 
Size table_block_parallelscan_estimate (Relation rel)
 
Size table_block_parallelscan_initialize (Relation rel, ParallelTableScanDesc pscan)
 
void table_block_parallelscan_reinitialize (Relation rel, ParallelTableScanDesc pscan)
 
BlockNumber table_block_parallelscan_nextpage (Relation rel, ParallelBlockTableScanWorker pbscanwork, ParallelBlockTableScanDesc pbscan)
 
void table_block_parallelscan_startblock_init (Relation rel, ParallelBlockTableScanWorker pbscanwork, ParallelBlockTableScanDesc pbscan, BlockNumber startblock, BlockNumber numblocks)
 
uint64 table_block_relation_size (Relation rel, ForkNumber forkNumber)
 
void table_block_relation_estimate_size (Relation rel, int32 *attr_widths, BlockNumber *pages, double *tuples, double *allvisfrac, Size overhead_bytes_per_tuple, Size usable_bytes_per_page)
 
const TableAmRoutineGetTableAmRoutine (Oid amhandler)
 
const TableAmRoutineGetHeapamTableAmRoutine (void)
 

Variables

PGDLLIMPORT chardefault_table_access_method
 
PGDLLIMPORT bool synchronize_seqscans
 

Macro Definition Documentation

◆ DEFAULT_TABLE_ACCESS_METHOD

#define DEFAULT_TABLE_ACCESS_METHOD   "heap"

Definition at line 29 of file tableam.h.

◆ SO_INTERNAL_FLAGS

#define SO_INTERNAL_FLAGS
Value:
@ SO_ALLOW_STRAT
Definition tableam.h:61
@ SO_TYPE_TIDRANGESCAN
Definition tableam.h:56
@ SO_TYPE_ANALYZE
Definition tableam.h:57
@ SO_TEMP_SNAPSHOT
Definition tableam.h:68
@ SO_TYPE_TIDSCAN
Definition tableam.h:55
@ SO_ALLOW_PAGEMODE
Definition tableam.h:65
@ SO_TYPE_SAMPLESCAN
Definition tableam.h:54
@ SO_ALLOW_SYNC
Definition tableam.h:63
@ SO_TYPE_SEQSCAN
Definition tableam.h:52
@ SO_TYPE_BITMAPSCAN
Definition tableam.h:53

Definition at line 84 of file tableam.h.

94{
95 /*
96 * Signals that the action succeeded (i.e. update/delete performed, lock
97 * was acquired)
98 */
99 TM_Ok,
100
101 /* The affected tuple wasn't visible to the relevant snapshot */
103
104 /* The affected tuple was already modified by the calling backend */
106
107 /*
108 * The affected tuple was updated by another transaction. This includes
109 * the case where tuple was moved to another partition.
110 */
112
113 /* The affected tuple was deleted by another transaction */
115
116 /*
117 * The affected tuple is currently being modified by another session. This
118 * will only be returned if table_(update/delete/lock_tuple) are
119 * instructed not to wait.
120 */
122
123 /* lock couldn't be acquired, action skipped. Only used by lock_tuple */
125} TM_Result;
126
127/*
128 * Result codes for table_update(..., update_indexes*..).
129 * Used to determine which indexes to update.
130 */
131typedef enum TU_UpdateIndexes
132{
133 /* No indexed columns were updated (incl. TID addressing of tuple) */
134 TU_None,
135
136 /* A non-summarizing indexed column was updated, or the TID has changed */
137 TU_All,
138
139 /* Only summarized columns were updated, TID is unchanged */
142
143/*
144 * When table_tuple_update, table_tuple_delete, or table_tuple_lock fail
145 * because the target tuple is already outdated, they fill in this struct to
146 * provide information to the caller about what happened. When those functions
147 * succeed, the contents of this struct should not be relied upon, except for
148 * `traversed`, which may be set in both success and failure cases.
149 *
150 * ctid is the target's ctid link: it is the same as the target's TID if the
151 * target was deleted, or the location of the replacement tuple if the target
152 * was updated.
153 *
154 * xmax is the outdating transaction's XID. If the caller wants to visit the
155 * replacement tuple, it must check that this matches before believing the
156 * replacement is really a match. This is InvalidTransactionId if the target
157 * was !LP_NORMAL (expected only for a TID retrieved from syscache).
158 *
159 * cmax is the outdating command's CID, but only when the failure code is
160 * TM_SelfModified (i.e., something in the current transaction outdated the
161 * tuple); otherwise cmax is zero. (We make this restriction because
162 * HeapTupleHeaderGetCmax doesn't work for tuples outdated in other
163 * transactions.)
164 *
165 * traversed indicates if an update chain was followed in order to try to lock
166 * the target tuple. (This may be set in both success and failure cases.)
167 */
168typedef struct TM_FailureData
169{
173 bool traversed;
175
176/*
177 * State used when calling table_index_delete_tuples().
178 *
179 * Represents the status of table tuples, referenced by table TID and taken by
180 * index AM from index tuples. State consists of high level parameters of the
181 * deletion operation, plus two mutable palloc()'d arrays for information
182 * about the status of individual table tuples. These are conceptually one
183 * single array. Using two arrays keeps the TM_IndexDelete struct small,
184 * which makes sorting the first array (the deltids array) fast.
185 *
186 * Some index AM callers perform simple index tuple deletion (by specifying
187 * bottomup = false), and include only known-dead deltids. These known-dead
188 * entries are all marked knowndeletable = true directly (typically these are
189 * TIDs from LP_DEAD-marked index tuples), but that isn't strictly required.
190 *
191 * Callers that specify bottomup = true are "bottom-up index deletion"
192 * callers. The considerations for the tableam are more subtle with these
193 * callers because they ask the tableam to perform highly speculative work,
194 * and might only expect the tableam to check a small fraction of all entries.
195 * Caller is not allowed to specify knowndeletable = true for any entry
196 * because everything is highly speculative. Bottom-up caller provides
197 * context and hints to tableam -- see comments below for details on how index
198 * AMs and tableams should coordinate during bottom-up index deletion.
199 *
200 * Simple index deletion callers may ask the tableam to perform speculative
201 * work, too. This is a little like bottom-up deletion, but not too much.
202 * The tableam will only perform speculative work when it's practically free
203 * to do so in passing for simple deletion caller (while always performing
204 * whatever work is needed to enable knowndeletable/LP_DEAD index tuples to
205 * be deleted within index AM). This is the real reason why it's possible for
206 * simple index deletion caller to specify knowndeletable = false up front
207 * (this means "check if it's possible for me to delete corresponding index
208 * tuple when it's cheap to do so in passing"). The index AM should only
209 * include "extra" entries for index tuples whose TIDs point to a table block
210 * that tableam is expected to have to visit anyway (in the event of a block
211 * orientated tableam). The tableam isn't strictly obligated to check these
212 * "extra" TIDs, but a block-based AM should always manage to do so in
213 * practice.
214 *
215 * The final contents of the deltids/status arrays are interesting to callers
216 * that ask tableam to perform speculative work (i.e. when _any_ items have
217 * knowndeletable set to false up front). These index AM callers will
218 * naturally need to consult final state to determine which index tuples are
219 * in fact deletable.
220 *
221 * The index AM can keep track of which index tuple relates to which deltid by
222 * setting idxoffnum (and/or relying on each entry being uniquely identifiable
223 * using tid), which is important when the final contents of the array will
224 * need to be interpreted -- the array can shrink from initial size after
225 * tableam processing and/or have entries in a new order (tableam may sort
226 * deltids array for its own reasons). Bottom-up callers may find that final
227 * ndeltids is 0 on return from call to tableam, in which case no index tuple
228 * deletions are possible. Simple deletion callers can rely on any entries
229 * they know to be deletable appearing in the final array as deletable.
230 */
231typedef struct TM_IndexDelete
232{
233 ItemPointerData tid; /* table TID from index tuple */
234 int16 id; /* Offset into TM_IndexStatus array */
236
237typedef struct TM_IndexStatus
238{
239 OffsetNumber idxoffnum; /* Index am page offset number */
240 bool knowndeletable; /* Currently known to be deletable? */
241
242 /* Bottom-up index deletion specific fields follow */
243 bool promising; /* Promising (duplicate) index tuple? */
244 int16 freespace; /* Space freed in index if deleted */
246
247/*
248 * Index AM/tableam coordination is central to the design of bottom-up index
249 * deletion. The index AM provides hints about where to look to the tableam
250 * by marking some entries as "promising". Index AM does this with duplicate
251 * index tuples that are strongly suspected to be old versions left behind by
252 * UPDATEs that did not logically modify indexed values. Index AM may find it
253 * helpful to only mark entries as promising when they're thought to have been
254 * affected by such an UPDATE in the recent past.
255 *
256 * Bottom-up index deletion casts a wide net at first, usually by including
257 * all TIDs on a target index page. It is up to the tableam to worry about
258 * the cost of checking transaction status information. The tableam is in
259 * control, but needs careful guidance from the index AM. Index AM requests
260 * that bottomupfreespace target be met, while tableam measures progress
261 * towards that goal by tallying the per-entry freespace value for known
262 * deletable entries. (All !bottomup callers can just set these space related
263 * fields to zero.)
264 */
265typedef struct TM_IndexDeleteOp
266{
267 Relation irel; /* Target index relation */
268 BlockNumber iblknum; /* Index block number (for error reports) */
269 bool bottomup; /* Bottom-up (not simple) deletion? */
270 int bottomupfreespace; /* Bottom-up space target */
271
272 /* Mutable per-TID information follows (index AM initializes entries) */
273 int ndeltids; /* Current # of deltids/status elements */
277
278/*
279 * "options" flag bits for table_tuple_insert. Access methods may define
280 * their own bits for internal use, as long as they don't collide with these.
281 */
282/* TABLE_INSERT_SKIP_WAL was 0x0001; RelationNeedsWAL() now governs */
283#define TABLE_INSERT_SKIP_FSM 0x0002
284#define TABLE_INSERT_FROZEN 0x0004
285#define TABLE_INSERT_NO_LOGICAL 0x0008
286
287/* "options" flag bits for table_tuple_delete */
288#define TABLE_DELETE_CHANGING_PARTITION (1 << 0)
289#define TABLE_DELETE_NO_LOGICAL (1 << 1)
290
291/* "options" flag bits for table_tuple_update */
292#define TABLE_UPDATE_NO_LOGICAL (1 << 0)
293
294/* flag bits for table_tuple_lock */
295/* Follow tuples whose update is in progress if lock modes don't conflict */
296#define TUPLE_LOCK_FLAG_LOCK_UPDATE_IN_PROGRESS (1 << 0)
297/* Follow update chain and lock latest version of tuple */
298#define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1)
299
300
301/* Typedef for callback function for table_index_build_scan */
303 ItemPointer tid,
304 Datum *values,
305 bool *isnull,
306 bool tupleIsAlive,
307 void *state);
308
309/*
310 * API struct for a table AM. Note this must be allocated in a
311 * server-lifetime manner, typically as a static const struct, which then gets
312 * returned by FormData_pg_am.amhandler.
313 *
314 * In most cases it's not appropriate to call the callbacks directly, use the
315 * table_* wrapper functions instead.
316 *
317 * GetTableAmRoutine() asserts that required callbacks are filled in, remember
318 * to update when adding a callback.
319 */
320typedef struct TableAmRoutine
321{
322 /* this must be set to T_TableAmRoutine */
324
325
326 /* ------------------------------------------------------------------------
327 * Slot related callbacks.
328 * ------------------------------------------------------------------------
329 */
330
331 /*
332 * Return slot implementation suitable for storing a tuple of this AM.
333 */
334 const TupleTableSlotOps *(*slot_callbacks) (Relation rel);
335
336
337 /* ------------------------------------------------------------------------
338 * Table scan callbacks.
339 * ------------------------------------------------------------------------
340 */
341
342 /*
343 * Start a scan of `rel`. The callback has to return a TableScanDesc,
344 * which will typically be embedded in a larger, AM specific, struct.
345 *
346 * If nkeys != 0, the results need to be filtered by those scan keys.
347 *
348 * pscan, if not NULL, will have already been initialized with
349 * parallelscan_initialize(), and has to be for the same relation. Will
350 * only be set coming from table_beginscan_parallel().
351 *
352 * `flags` is a bitmask indicating the type of scan (ScanOptions's
353 * SO_TYPE_*, currently only one may be specified), options controlling
354 * the scan's behaviour (ScanOptions's SO_ALLOW_*, several may be
355 * specified, an AM may ignore unsupported ones), whether the snapshot
356 * needs to be deallocated at scan_end (ScanOptions's SO_TEMP_SNAPSHOT),
357 * and any number of the other ScanOptions values.
358 */
360 Snapshot snapshot,
361 int nkeys, ScanKeyData *key,
363 uint32 flags);
364
365 /*
366 * Release resources and deallocate scan. If TableScanDesc.temp_snap,
367 * TableScanDesc.rs_snapshot needs to be unregistered.
368 */
369 void (*scan_end) (TableScanDesc scan);
370
371 /*
372 * Restart relation scan. If set_params is set to true, allow_{strat,
373 * sync, pagemode} (see scan_begin) changes should be taken into account.
374 */
376 bool set_params, bool allow_strat,
377 bool allow_sync, bool allow_pagemode);
378
379 /*
380 * Return next tuple from `scan`, store in slot.
381 */
383 ScanDirection direction,
384 TupleTableSlot *slot);
385
386 /*-----------
387 * Optional functions to provide scanning for ranges of ItemPointers.
388 * Implementations must either provide both of these functions, or neither
389 * of them.
390 *
391 * Implementations of scan_set_tidrange must themselves handle
392 * ItemPointers of any value. i.e, they must handle each of the following:
393 *
394 * 1) mintid or maxtid is beyond the end of the table; and
395 * 2) mintid is above maxtid; and
396 * 3) item offset for mintid or maxtid is beyond the maximum offset
397 * allowed by the AM.
398 *
399 * Implementations can assume that scan_set_tidrange is always called
400 * before scan_getnextslot_tidrange or after scan_rescan and before any
401 * further calls to scan_getnextslot_tidrange.
402 */
406
407 /*
408 * Return next tuple from `scan` that's in the range of TIDs defined by
409 * scan_set_tidrange.
410 */
412 ScanDirection direction,
413 TupleTableSlot *slot);
414
415 /* ------------------------------------------------------------------------
416 * Parallel table scan related functions.
417 * ------------------------------------------------------------------------
418 */
419
420 /*
421 * Estimate the size of shared memory needed for a parallel scan of this
422 * relation. The snapshot does not need to be accounted for.
423 */
425
426 /*
427 * Initialize ParallelTableScanDesc for a parallel scan of this relation.
428 * `pscan` will be sized according to parallelscan_estimate() for the same
429 * relation.
430 */
433
434 /*
435 * Reinitialize `pscan` for a new scan. `rel` will be the same relation as
436 * when `pscan` was initialized by parallelscan_initialize.
437 */
440
441
442 /* ------------------------------------------------------------------------
443 * Index Scan Callbacks
444 * ------------------------------------------------------------------------
445 */
446
447 /*
448 * Prepare to fetch tuples from the relation, as needed when fetching
449 * tuples for an index scan. The callback has to return an
450 * IndexFetchTableData, which the AM will typically embed in a larger
451 * structure with additional information.
452 *
453 * flags is a bitmask of ScanOptions affecting underlying table scan
454 * behavior. See scan_begin() for more information on passing these.
455 *
456 * Tuples for an index scan can then be fetched via index_fetch_tuple.
457 */
458 struct IndexFetchTableData *(*index_fetch_begin) (Relation rel, uint32 flags);
459
460 /*
461 * Reset index fetch. Typically this will release cross index fetch
462 * resources held in IndexFetchTableData.
463 */
465
466 /*
467 * Release resources and deallocate index fetch.
468 */
470
471 /*
472 * Fetch tuple at `tid` into `slot`, after doing a visibility test
473 * according to `snapshot`. If a tuple was found and passed the visibility
474 * test, return true, false otherwise.
475 *
476 * Note that AMs that do not necessarily update indexes when indexed
477 * columns do not change, need to return the current/correct version of
478 * the tuple that is visible to the snapshot, even if the tid points to an
479 * older version of the tuple.
480 *
481 * *call_again is false on the first call to index_fetch_tuple for a tid.
482 * If there potentially is another tuple matching the tid, *call_again
483 * needs to be set to true by index_fetch_tuple, signaling to the caller
484 * that index_fetch_tuple should be called again for the same tid.
485 *
486 * *all_dead, if all_dead is not NULL, should be set to true by
487 * index_fetch_tuple iff it is guaranteed that no backend needs to see
488 * that tuple. Index AMs can use that to avoid returning that tid in
489 * future searches.
490 */
492 ItemPointer tid,
493 Snapshot snapshot,
494 TupleTableSlot *slot,
495 bool *call_again, bool *all_dead);
496
497
498 /* ------------------------------------------------------------------------
499 * Callbacks for non-modifying operations on individual tuples
500 * ------------------------------------------------------------------------
501 */
502
503 /*
504 * Fetch tuple at `tid` into `slot`, after doing a visibility test
505 * according to `snapshot`. If a tuple was found and passed the visibility
506 * test, returns true, false otherwise.
507 */
509 ItemPointer tid,
510 Snapshot snapshot,
511 TupleTableSlot *slot);
512
513 /*
514 * Is tid valid for a scan of this relation.
515 */
517 ItemPointer tid);
518
519 /*
520 * Return the latest version of the tuple at `tid`, by updating `tid` to
521 * point at the newest version.
522 */
524 ItemPointer tid);
525
526 /*
527 * Does the tuple in `slot` satisfy `snapshot`? The slot needs to be of
528 * the appropriate type for the AM.
529 */
531 TupleTableSlot *slot,
532 Snapshot snapshot);
533
534 /* see table_index_delete_tuples() */
537
538
539 /* ------------------------------------------------------------------------
540 * Manipulations of physical tuples.
541 * ------------------------------------------------------------------------
542 */
543
544 /* see table_tuple_insert() for reference about parameters */
547 BulkInsertStateData *bistate);
548
549 /* see table_tuple_insert_speculative() for reference about parameters */
551 TupleTableSlot *slot,
554 BulkInsertStateData *bistate,
556
557 /* see table_tuple_complete_speculative() for reference about parameters */
559 TupleTableSlot *slot,
561 bool succeeded);
562
563 /* see table_multi_insert() for reference about parameters */
564 void (*multi_insert) (Relation rel, TupleTableSlot **slots, int nslots,
566
567 /* see table_tuple_delete() for reference about parameters */
569 ItemPointer tid,
572 Snapshot snapshot,
574 bool wait,
575 TM_FailureData *tmfd);
576
577 /* see table_tuple_update() for reference about parameters */
580 TupleTableSlot *slot,
583 Snapshot snapshot,
585 bool wait,
586 TM_FailureData *tmfd,
587 LockTupleMode *lockmode,
589
590 /* see table_tuple_lock() for reference about parameters */
592 ItemPointer tid,
593 Snapshot snapshot,
594 TupleTableSlot *slot,
598 uint8 flags,
599 TM_FailureData *tmfd);
600
601 /*
602 * Perform operations necessary to complete insertions made via
603 * tuple_insert and multi_insert with a BulkInsertState specified. In-tree
604 * access methods ceased to use this.
605 *
606 * Typically callers of tuple_insert and multi_insert will just pass all
607 * the flags that apply to them, and each AM has to decide which of them
608 * make sense for it, and then only take actions in finish_bulk_insert for
609 * those flags, and ignore others.
610 *
611 * Optional callback.
612 */
614
615
616 /* ------------------------------------------------------------------------
617 * DDL related functionality.
618 * ------------------------------------------------------------------------
619 */
620
621 /*
622 * This callback needs to create new relation storage for `rel`, with
623 * appropriate durability behaviour for `persistence`.
624 *
625 * Note that only the subset of the relcache filled by
626 * RelationBuildLocalRelation() can be relied upon and that the relation's
627 * catalog entries will either not yet exist (new relation), or will still
628 * reference the old relfilelocator.
629 *
630 * As output *freezeXid, *minmulti must be set to the values appropriate
631 * for pg_class.{relfrozenxid, relminmxid}. For AMs that don't need those
632 * fields to be filled they can be set to InvalidTransactionId and
633 * InvalidMultiXactId, respectively.
634 *
635 * See also table_relation_set_new_filelocator().
636 */
639 char persistence,
642
643 /*
644 * This callback needs to remove all contents from `rel`'s current
645 * relfilelocator. No provisions for transactional behaviour need to be
646 * made. Often this can be implemented by truncating the underlying
647 * storage to its minimal size.
648 *
649 * See also table_relation_nontransactional_truncate().
650 */
652
653 /*
654 * See table_relation_copy_data().
655 *
656 * This can typically be implemented by directly copying the underlying
657 * storage, unless it contains references to the tablespace internally.
658 */
661
662 /* See table_relation_copy_for_cluster() */
666 bool use_sort,
667 TransactionId OldestXmin,
668 Snapshot snapshot,
671 double *num_tuples,
672 double *tups_vacuumed,
673 double *tups_recently_dead);
674
675 /*
676 * React to VACUUM command on the relation. The VACUUM can be triggered by
677 * a user or by autovacuum. The specific actions performed by the AM will
678 * depend heavily on the individual AM.
679 *
680 * On entry a transaction is already established, and the relation is
681 * locked with a ShareUpdateExclusive lock.
682 *
683 * Note that neither VACUUM FULL (and CLUSTER), nor ANALYZE go through
684 * this routine, even if (for ANALYZE) it is part of the same VACUUM
685 * command.
686 *
687 * There probably, in the future, needs to be a separate callback to
688 * integrate with autovacuum's scheduling.
689 */
691 const VacuumParams *params,
692 BufferAccessStrategy bstrategy);
693
694 /*
695 * Prepare to analyze block `blockno` of `scan`. The scan has been started
696 * with table_beginscan_analyze(). See also
697 * table_scan_analyze_next_block().
698 *
699 * The callback may acquire resources like locks that are held until
700 * table_scan_analyze_next_tuple() returns false. It e.g. can make sense
701 * to hold a lock until all tuples on a block have been analyzed by
702 * scan_analyze_next_tuple.
703 *
704 * The callback can return false if the block is not suitable for
705 * sampling, e.g. because it's a metapage that could never contain tuples.
706 *
707 * XXX: This obviously is primarily suited for block-based AMs. It's not
708 * clear what a good interface for non block based AMs would be, so there
709 * isn't one yet.
710 */
712 ReadStream *stream);
713
714 /*
715 * See table_scan_analyze_next_tuple().
716 *
717 * Not every AM might have a meaningful concept of dead rows, in which
718 * case it's OK to not increment *deadrows - but note that that may
719 * influence autovacuum scheduling (see comment for relation_vacuum
720 * callback).
721 */
723 double *liverows,
724 double *deadrows,
725 TupleTableSlot *slot);
726
727 /* see table_index_build_range_scan for reference about parameters */
731 bool allow_sync,
732 bool anyvisible,
733 bool progress,
737 void *callback_state,
738 TableScanDesc scan);
739
740 /* see table_index_validate_scan for reference about parameters */
744 Snapshot snapshot,
746
747
748 /* ------------------------------------------------------------------------
749 * Miscellaneous functions.
750 * ------------------------------------------------------------------------
751 */
752
753 /*
754 * See table_relation_size().
755 *
756 * Note that currently a few callers use the MAIN_FORKNUM size to figure
757 * out the range of potentially interesting blocks (brin, analyze). It's
758 * probable that we'll need to revise the interface for those at some
759 * point.
760 */
762
763
764 /*
765 * This callback should return true if the relation requires a TOAST table
766 * and false if it does not. It may wish to examine the relation's tuple
767 * descriptor before making a decision, but if it uses some other method
768 * of storing large values (or if it does not support them) it can simply
769 * return false.
770 */
772
773 /*
774 * This callback should return the OID of the table AM that implements
775 * TOAST tables for this AM. If the relation_needs_toast_table callback
776 * always returns false, this callback is not required.
777 */
779
780 /*
781 * This callback is invoked when detoasting a value stored in a toast
782 * table implemented by this AM. See table_relation_fetch_toast_slice()
783 * for more details.
784 */
789 varlena *result);
790
791
792 /* ------------------------------------------------------------------------
793 * Planner related functions.
794 * ------------------------------------------------------------------------
795 */
796
797 /*
798 * See table_relation_estimate_size().
799 *
800 * While block oriented, it shouldn't be too hard for an AM that doesn't
801 * internally use blocks to convert into a usable representation.
802 *
803 * This differs from the relation_size callback by returning size
804 * estimates (both relation size and tuple count) for planning purposes,
805 * rather than returning a currently correct estimate.
806 */
808 BlockNumber *pages, double *tuples,
809 double *allvisfrac);
810
811
812 /* ------------------------------------------------------------------------
813 * Executor related functions.
814 * ------------------------------------------------------------------------
815 */
816
817 /*
818 * Fetch the next tuple of a bitmap table scan into `slot` and return true
819 * if a visible tuple was found, false otherwise.
820 *
821 * `lossy_pages` is incremented if the bitmap is lossy for the selected
822 * page; otherwise, `exact_pages` is incremented. These are tracked for
823 * display in EXPLAIN ANALYZE output.
824 *
825 * Prefetching additional data from the bitmap is left to the table AM.
826 *
827 * This is an optional callback.
828 */
830 TupleTableSlot *slot,
831 bool *recheck,
832 uint64 *lossy_pages,
833 uint64 *exact_pages);
834
835 /*
836 * Prepare to fetch tuples from the next block in a sample scan. Return
837 * false if the sample scan is finished, true otherwise. `scan` was
838 * started via table_beginscan_sampling().
839 *
840 * Typically this will first determine the target block by calling the
841 * TsmRoutine's NextSampleBlock() callback if not NULL, or alternatively
842 * perform a sequential scan over all blocks. The determined block is
843 * then typically read and pinned.
844 *
845 * As the TsmRoutine interface is block based, a block needs to be passed
846 * to NextSampleBlock(). If that's not appropriate for an AM, it
847 * internally needs to perform mapping between the internal and a block
848 * based representation.
849 *
850 * Note that it's not acceptable to hold deadlock prone resources such as
851 * lwlocks until scan_sample_next_tuple() has exhausted the tuples on the
852 * block - the tuple is likely to be returned to an upper query node, and
853 * the next call could be off a long while. Holding buffer pins and such
854 * is obviously OK.
855 *
856 * Currently it is required to implement this interface, as there's no
857 * alternative way (contrary e.g. to bitmap scans) to implement sample
858 * scans. If infeasible to implement, the AM may raise an error.
859 */
862
863 /*
864 * This callback, only called after scan_sample_next_block has returned
865 * true, should determine the next tuple to be returned from the selected
866 * block using the TsmRoutine's NextSampleTuple() callback.
867 *
868 * The callback needs to perform visibility checks, and only return
869 * visible tuples. That obviously can mean calling NextSampleTuple()
870 * multiple times.
871 *
872 * The TsmRoutine interface assumes that there's a maximum offset on a
873 * given page, so if that doesn't apply to an AM, it needs to emulate that
874 * assumption somehow.
875 */
878 TupleTableSlot *slot);
879
881
882
883/* ----------------------------------------------------------------------------
884 * Slot functions.
885 * ----------------------------------------------------------------------------
886 */
887
888/*
889 * Returns slot callbacks suitable for holding tuples of the appropriate type
890 * for the relation. Works for tables, views, foreign tables and partitioned
891 * tables.
892 */
893extern const TupleTableSlotOps *table_slot_callbacks(Relation relation);
894
895/*
896 * Returns slot using the callbacks returned by table_slot_callbacks(), and
897 * registers it on *reglist.
898 */
900
901
902/* ----------------------------------------------------------------------------
903 * Table scan functions.
904 * ----------------------------------------------------------------------------
905 */
906
907/*
908 * A wrapper around the Table Access Method scan_begin callback, to centralize
909 * error checking. All calls to ->scan_begin() should go through this
910 * function.
911 *
912 * The caller-provided user_flags are validated against SO_INTERNAL_FLAGS to
913 * catch callers that accidentally pass scan-type or other internal flags.
914 */
915static TableScanDesc
916table_beginscan_common(Relation rel, Snapshot snapshot, int nkeys,
919{
921 Assert((flags & ~SO_INTERNAL_FLAGS) == 0);
922 flags |= user_flags;
923
924 /*
925 * We don't allow scans to be started while CheckXidAlive is set, except
926 * via systable_beginscan() et al. See detailed comments in xact.c where
927 * these variables are declared.
928 */
930 elog(ERROR, "scan started during logical decoding");
931
932 return rel->rd_tableam->scan_begin(rel, snapshot, nkeys, key, pscan, flags);
933}
934
935/*
936 * Start a scan of `rel`. Returned tuples pass a visibility test of
937 * `snapshot`, and if nkeys != 0, the results are filtered by those scan keys.
938 *
939 * flags is a bitmask of ScanOptions. No SO_INTERNAL_FLAGS are permitted.
940 */
941static inline TableScanDesc
943 int nkeys, ScanKeyData *key, uint32 flags)
944{
947
948 return table_beginscan_common(rel, snapshot, nkeys, key, NULL,
950}
951
952/*
953 * Like table_beginscan(), but for scanning catalog. It'll automatically use a
954 * snapshot appropriate for scanning catalog relations.
955 */
956extern TableScanDesc table_beginscan_catalog(Relation relation, int nkeys,
957 ScanKeyData *key);
958
959/*
960 * Like table_beginscan(), but table_beginscan_strat() offers an extended API
961 * that lets the caller control whether a nondefault buffer access strategy
962 * can be used, and whether syncscan can be chosen (possibly resulting in the
963 * scan not starting from block zero). Both of these default to true with
964 * plain table_beginscan.
965 */
966static inline TableScanDesc
968 int nkeys, ScanKeyData *key,
969 bool allow_strat, bool allow_sync)
970{
972
973 if (allow_strat)
975 if (allow_sync)
977
978 return table_beginscan_common(rel, snapshot, nkeys, key, NULL,
979 flags, SO_NONE);
980}
981
982/*
983 * table_beginscan_bm is an alternative entry point for setting up a
984 * TableScanDesc for a bitmap heap scan. Although that scan technology is
985 * really quite unlike a standard seqscan, there is just enough commonality to
986 * make it worth using the same data structure.
987 *
988 * flags is a bitmask of ScanOptions. No SO_INTERNAL_FLAGS are permitted.
989 */
990static inline TableScanDesc
992 int nkeys, ScanKeyData *key, uint32 flags)
993{
995
996 return table_beginscan_common(rel, snapshot, nkeys, key, NULL,
998}
999
1000/*
1001 * table_beginscan_sampling is an alternative entry point for setting up a
1002 * TableScanDesc for a TABLESAMPLE scan. As with bitmap scans, it's worth
1003 * using the same data structure although the behavior is rather different.
1004 * In addition to the options offered by table_beginscan_strat, this call
1005 * also allows control of whether page-mode visibility checking is used.
1006 *
1007 * flags is a bitmask of ScanOptions. No SO_INTERNAL_FLAGS are permitted.
1008 */
1009static inline TableScanDesc
1011 int nkeys, ScanKeyData *key,
1012 bool allow_strat, bool allow_sync,
1014{
1016
1017 if (allow_strat)
1019 if (allow_sync)
1021 if (allow_pagemode)
1023
1024 return table_beginscan_common(rel, snapshot, nkeys, key, NULL,
1026}
1027
1028/*
1029 * table_beginscan_tid is an alternative entry point for setting up a
1030 * TableScanDesc for a Tid scan. As with bitmap scans, it's worth using
1031 * the same data structure although the behavior is rather different.
1032 */
1033static inline TableScanDesc
1035{
1037
1038 return table_beginscan_common(rel, snapshot, 0, NULL, NULL,
1039 flags, SO_NONE);
1040}
1041
1042/*
1043 * table_beginscan_analyze is an alternative entry point for setting up a
1044 * TableScanDesc for an ANALYZE scan. As with bitmap scans, it's worth using
1045 * the same data structure although the behavior is rather different.
1046 */
1047static inline TableScanDesc
1049{
1051
1053 flags, SO_NONE);
1054}
1055
1056/*
1057 * End relation scan.
1058 */
1059static inline void
1061{
1062 scan->rs_rd->rd_tableam->scan_end(scan);
1063}
1064
1065/*
1066 * Restart a relation scan.
1067 */
1068static inline void
1070{
1071 scan->rs_rd->rd_tableam->scan_rescan(scan, key, false, false, false, false);
1072}
1073
1074/*
1075 * Restart a relation scan after changing params.
1076 *
1077 * This call allows changing the buffer strategy, syncscan, and pagemode
1078 * options before starting a fresh scan. Note that although the actual use of
1079 * syncscan might change (effectively, enabling or disabling reporting), the
1080 * previously selected startblock will be kept.
1081 */
1082static inline void
1084 bool allow_strat, bool allow_sync, bool allow_pagemode)
1085{
1086 scan->rs_rd->rd_tableam->scan_rescan(scan, key, true,
1089}
1090
1091/*
1092 * Return next tuple from `scan`, store in slot.
1093 */
1094static inline bool
1096{
1097 slot->tts_tableOid = RelationGetRelid(sscan->rs_rd);
1098
1099 /* We don't expect actual scans using NoMovementScanDirection */
1100 Assert(direction == ForwardScanDirection ||
1101 direction == BackwardScanDirection);
1102
1103 return sscan->rs_rd->rd_tableam->scan_getnextslot(sscan, direction, slot);
1104}
1105
1106/* ----------------------------------------------------------------------------
1107 * TID Range scanning related functions.
1108 * ----------------------------------------------------------------------------
1109 */
1110
1111/*
1112 * table_beginscan_tidrange is the entry point for setting up a TableScanDesc
1113 * for a TID range scan.
1114 *
1115 * flags is a bitmask of ScanOptions. No SO_INTERNAL_FLAGS are permitted.
1116 */
1117static inline TableScanDesc
1121{
1124
1125 sscan = table_beginscan_common(rel, snapshot, 0, NULL, NULL,
1127
1128 /* Set the range of TIDs to scan */
1129 sscan->rs_rd->rd_tableam->scan_set_tidrange(sscan, mintid, maxtid);
1130
1131 return sscan;
1132}
1133
1134/*
1135 * table_rescan_tidrange resets the scan position and sets the minimum and
1136 * maximum TID range to scan for a TableScanDesc created by
1137 * table_beginscan_tidrange.
1138 */
1139static inline void
1142{
1143 /* Ensure table_beginscan_tidrange() was used. */
1144 Assert((sscan->rs_flags & SO_TYPE_TIDRANGESCAN) != 0);
1145
1146 sscan->rs_rd->rd_tableam->scan_rescan(sscan, NULL, false, false, false, false);
1147 sscan->rs_rd->rd_tableam->scan_set_tidrange(sscan, mintid, maxtid);
1148}
1149
1150/*
1151 * Fetch the next tuple from `sscan` for a TID range scan created by
1152 * table_beginscan_tidrange(). Stores the tuple in `slot` and returns true,
1153 * or returns false if no more tuples exist in the range.
1154 */
1155static inline bool
1157 TupleTableSlot *slot)
1158{
1159 /* Ensure table_beginscan_tidrange() was used. */
1160 Assert((sscan->rs_flags & SO_TYPE_TIDRANGESCAN) != 0);
1161
1162 /* We don't expect actual scans using NoMovementScanDirection */
1163 Assert(direction == ForwardScanDirection ||
1164 direction == BackwardScanDirection);
1165
1166 return sscan->rs_rd->rd_tableam->scan_getnextslot_tidrange(sscan,
1167 direction,
1168 slot);
1169}
1170
1171
1172/* ----------------------------------------------------------------------------
1173 * Parallel table scan related functions.
1174 * ----------------------------------------------------------------------------
1175 */
1176
1177/*
1178 * Estimate the size of shared memory needed for a parallel scan of this
1179 * relation.
1180 */
1182
1183/*
1184 * Initialize ParallelTableScanDesc for a parallel scan of this
1185 * relation. `pscan` needs to be sized according to parallelscan_estimate()
1186 * for the same relation. Call this just once in the leader process; then,
1187 * individual workers attach via table_beginscan_parallel.
1188 */
1191 Snapshot snapshot);
1192
1193/*
1194 * Begin a parallel scan. `pscan` needs to have been initialized with
1195 * table_parallelscan_initialize(), for the same relation. The initialization
1196 * does not need to have happened in this backend.
1197 *
1198 * flags is a bitmask of ScanOptions. No SO_INTERNAL_FLAGS are permitted.
1199 *
1200 * Caller must hold a suitable lock on the relation.
1201 */
1204 uint32 flags);
1205
1206/*
1207 * Begin a parallel tid range scan. `pscan` needs to have been initialized
1208 * with table_parallelscan_initialize(), for the same relation. The
1209 * initialization does not need to have happened in this backend.
1210 *
1211 * flags is a bitmask of ScanOptions. No SO_INTERNAL_FLAGS are permitted.
1212 *
1213 * Caller must hold a suitable lock on the relation.
1214 */
1217 uint32 flags);
1218
1219/*
1220 * Restart a parallel scan. Call this in the leader process. Caller is
1221 * responsible for making sure that all workers have finished the scan
1222 * beforehand.
1223 */
1224static inline void
1226{
1228}
1229
1230
1231/* ----------------------------------------------------------------------------
1232 * Index scan related functions.
1233 * ----------------------------------------------------------------------------
1234 */
1235
1236/*
1237 * Prepare to fetch tuples from the relation, as needed when fetching tuples
1238 * for an index scan.
1239 *
1240 * flags is a bitmask of ScanOptions. No SO_INTERNAL_FLAGS are permitted.
1241 *
1242 * Tuples for an index scan can then be fetched via table_index_fetch_tuple().
1243 */
1244static inline IndexFetchTableData *
1246{
1247 Assert((flags & SO_INTERNAL_FLAGS) == 0);
1248
1249 /*
1250 * We don't allow scans to be started while CheckXidAlive is set, except
1251 * via systable_beginscan() et al. See detailed comments in xact.c where
1252 * these variables are declared.
1253 */
1255 elog(ERROR, "scan started during logical decoding");
1256
1258}
1259
1260/*
1261 * Reset index fetch. Typically this will release cross index fetch resources
1262 * held in IndexFetchTableData.
1263 */
1264static inline void
1266{
1267 scan->rel->rd_tableam->index_fetch_reset(scan);
1268}
1269
1270/*
1271 * Release resources and deallocate index fetch.
1272 */
1273static inline void
1275{
1276 scan->rel->rd_tableam->index_fetch_end(scan);
1277}
1278
1279/*
1280 * Fetches, as part of an index scan, tuple at `tid` into `slot`, after doing
1281 * a visibility test according to `snapshot`. If a tuple was found and passed
1282 * the visibility test, returns true, false otherwise. Note that *tid may be
1283 * modified when we return true (see later remarks on multiple row versions
1284 * reachable via a single index entry).
1285 *
1286 * *call_again needs to be false on the first call to table_index_fetch_tuple() for
1287 * a tid. If there potentially is another tuple matching the tid, *call_again
1288 * will be set to true, signaling that table_index_fetch_tuple() should be called
1289 * again for the same tid.
1290 *
1291 * *all_dead, if all_dead is not NULL, will be set to true by
1292 * table_index_fetch_tuple() iff it is guaranteed that no backend needs to see
1293 * that tuple. Index AMs can use that to avoid returning that tid in future
1294 * searches.
1295 *
1296 * The difference between this function and table_tuple_fetch_row_version()
1297 * is that this function returns the currently visible version of a row if
1298 * the AM supports storing multiple row versions reachable via a single index
1299 * entry (like heap's HOT). Whereas table_tuple_fetch_row_version() only
1300 * evaluates the tuple exactly at `tid`. Outside of index entry ->table tuple
1301 * lookups, table_tuple_fetch_row_version() is what's usually needed.
1302 */
1303static inline bool
1305 ItemPointer tid,
1306 Snapshot snapshot,
1307 TupleTableSlot *slot,
1308 bool *call_again, bool *all_dead)
1309{
1310 return scan->rel->rd_tableam->index_fetch_tuple(scan, tid, snapshot,
1311 slot, call_again,
1312 all_dead);
1313}
1314
1315/*
1316 * This is a convenience wrapper around table_index_fetch_tuple() which
1317 * returns whether there are table tuple items corresponding to an index
1318 * entry. This likely is only useful to verify if there's a conflict in a
1319 * unique index.
1320 */
1322 ItemPointer tid,
1323 Snapshot snapshot,
1324 bool *all_dead);
1325
1326
1327/* ------------------------------------------------------------------------
1328 * Functions for non-modifying operations on individual tuples
1329 * ------------------------------------------------------------------------
1330 */
1331
1332
1333/*
1334 * Fetch tuple at `tid` into `slot`, after doing a visibility test according to
1335 * `snapshot`. If a tuple was found and passed the visibility test, returns
1336 * true, false otherwise.
1337 *
1338 * See table_index_fetch_tuple's comment about what the difference between
1339 * these functions is. It is correct to use this function outside of index
1340 * entry->table tuple lookups.
1341 */
1342static inline bool
1344 ItemPointer tid,
1345 Snapshot snapshot,
1346 TupleTableSlot *slot)
1347{
1348 /*
1349 * We don't expect direct calls to table_tuple_fetch_row_version with
1350 * valid CheckXidAlive for catalog or regular tables. See detailed
1351 * comments in xact.c where these variables are declared.
1352 */
1354 elog(ERROR, "unexpected table_tuple_fetch_row_version call during logical decoding");
1355
1356 return rel->rd_tableam->tuple_fetch_row_version(rel, tid, snapshot, slot);
1357}
1358
1359/*
1360 * Verify that `tid` is a potentially valid tuple identifier. That doesn't
1361 * mean that the pointed to row needs to exist or be visible, but that
1362 * attempting to fetch the row (e.g. with table_tuple_get_latest_tid() or
1363 * table_tuple_fetch_row_version()) should not error out if called with that
1364 * tid.
1365 *
1366 * `scan` needs to have been started via table_beginscan().
1367 */
1368static inline bool
1370{
1371 return scan->rs_rd->rd_tableam->tuple_tid_valid(scan, tid);
1372}
1373
1374/*
1375 * Return the latest version of the tuple at `tid`, by updating `tid` to
1376 * point at the newest version.
1377 */
1379
1380/*
1381 * Return true iff tuple in slot satisfies the snapshot.
1382 *
1383 * This assumes the slot's tuple is valid, and of the appropriate type for the
1384 * AM.
1385 *
1386 * Some AMs might modify the data underlying the tuple as a side-effect. If so
1387 * they ought to mark the relevant buffer dirty.
1388 */
1389static inline bool
1391 Snapshot snapshot)
1392{
1393 return rel->rd_tableam->tuple_satisfies_snapshot(rel, slot, snapshot);
1394}
1395
1396/*
1397 * Determine which index tuples are safe to delete based on their table TID.
1398 *
1399 * Determines which entries from index AM caller's TM_IndexDeleteOp state
1400 * point to vacuumable table tuples. Entries that are found by tableam to be
1401 * vacuumable are naturally safe for index AM to delete, and so get directly
1402 * marked as deletable. See comments above TM_IndexDelete and comments above
1403 * TM_IndexDeleteOp for full details.
1404 *
1405 * Returns a snapshotConflictHorizon transaction ID that caller places in
1406 * its index deletion WAL record. This might be used during subsequent REDO
1407 * of the WAL record when in Hot Standby mode -- a recovery conflict for the
1408 * index deletion operation might be required on the standby.
1409 */
1410static inline TransactionId
1412{
1414}
1415
1416
1417/* ----------------------------------------------------------------------------
1418 * Functions for manipulations of physical tuples.
1419 * ----------------------------------------------------------------------------
1420 */
1421
1422/*
1423 * Insert a tuple from a slot into table AM routine.
1424 *
1425 * The options bitmask allows the caller to specify options that may change the
1426 * behaviour of the AM. The AM will ignore options that it does not support.
1427 *
1428 * If the TABLE_INSERT_SKIP_FSM option is specified, AMs are free to not reuse
1429 * free space in the relation. This can save some cycles when we know the
1430 * relation is new and doesn't contain useful amounts of free space.
1431 * TABLE_INSERT_SKIP_FSM is commonly passed directly to
1432 * RelationGetBufferForTuple. See that method for more information.
1433 *
1434 * TABLE_INSERT_FROZEN should only be specified for inserts into
1435 * relation storage created during the current subtransaction and when
1436 * there are no prior snapshots or pre-existing portals open.
1437 * This causes rows to be frozen, which is an MVCC violation and
1438 * requires explicit options chosen by user.
1439 *
1440 * TABLE_INSERT_NO_LOGICAL force-disables the emitting of logical decoding
1441 * information for the tuple. This should solely be used during table rewrites
1442 * where RelationIsLogicallyLogged(relation) is not yet accurate for the new
1443 * relation.
1444 *
1445 * Note that most of these options will be applied when inserting into the
1446 * heap's TOAST table, too, if the tuple requires any out-of-line data.
1447 *
1448 * The BulkInsertState object (if any; bistate can be NULL for default
1449 * behavior) is also just passed through to RelationGetBufferForTuple. If
1450 * `bistate` is provided, table_finish_bulk_insert() needs to be called.
1451 *
1452 * On return the slot's tts_tid and tts_tableOid are updated to reflect the
1453 * insertion. But note that any toasting of fields within the slot is NOT
1454 * reflected in the slots contents.
1455 */
1456static inline void
1459{
1461 bistate);
1462}
1463
1464/*
1465 * Perform a "speculative insertion". These can be backed out afterwards
1466 * without aborting the whole transaction. Other sessions can wait for the
1467 * speculative insertion to be confirmed, turning it into a regular tuple, or
1468 * aborted, as if it never existed. Speculatively inserted tuples behave as
1469 * "value locks" of short duration, used to implement INSERT .. ON CONFLICT.
1470 *
1471 * A transaction having performed a speculative insertion has to either abort,
1472 * or finish the speculative insertion with
1473 * table_tuple_complete_speculative(succeeded = ...).
1474 */
1475static inline void
1478 BulkInsertStateData *bistate,
1480{
1482 bistate, specToken);
1483}
1484
1485/*
1486 * Complete "speculative insertion" started in the same transaction. If
1487 * succeeded is true, the tuple is fully inserted, if false, it's removed.
1488 */
1489static inline void
1492{
1494 succeeded);
1495}
1496
1497/*
1498 * Insert multiple tuples into a table.
1499 *
1500 * This is like table_tuple_insert(), but inserts multiple tuples in one
1501 * operation. That's often faster than calling table_tuple_insert() in a loop,
1502 * because e.g. the AM can reduce WAL logging and page locking overhead.
1503 *
1504 * Except for taking `nslots` tuples as input, and an array of TupleTableSlots
1505 * in `slots`, the parameters for table_multi_insert() are the same as for
1506 * table_tuple_insert().
1507 *
1508 * Note: this leaks memory into the current memory context. You can create a
1509 * temporary context before calling this, if that's a problem.
1510 */
1511static inline void
1512table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots,
1514{
1515 rel->rd_tableam->multi_insert(rel, slots, nslots,
1516 cid, options, bistate);
1517}
1518
1519/*
1520 * Delete a tuple.
1521 *
1522 * NB: do not call this directly unless prepared to deal with
1523 * concurrent-update conditions. Use simple_table_tuple_delete instead.
1524 *
1525 * Input parameters:
1526 * rel - table to be modified (caller must hold suitable lock)
1527 * tid - TID of tuple to be deleted
1528 * cid - delete command ID (used for visibility test, and stored into
1529 * cmax if successful)
1530 * options - bitmask of options. Supported values:
1531 * TABLE_DELETE_CHANGING_PARTITION: the tuple is being moved to another
1532 * partition table due to an update of the partition key.
1533 * crosscheck - if not InvalidSnapshot, also check tuple against this
1534 * wait - true if should wait for any conflicting update to commit/abort
1535 *
1536 * Output parameters:
1537 * tmfd - filled in failure cases (see below)
1538 *
1539 * Normal, successful return value is TM_Ok, which means we did actually
1540 * delete it. Failure return codes are TM_SelfModified, TM_Updated, and
1541 * TM_BeingModified (the last only possible if wait == false).
1542 *
1543 * In the failure cases, the routine fills *tmfd with the tuple's t_ctid,
1544 * t_xmax, and, if possible, t_cmax. See comments for struct
1545 * TM_FailureData for additional info.
1546 */
1547static inline TM_Result
1550 bool wait, TM_FailureData *tmfd)
1551{
1552 return rel->rd_tableam->tuple_delete(rel, tid, cid, options,
1553 snapshot, crosscheck,
1554 wait, tmfd);
1555}
1556
1557/*
1558 * Update a tuple.
1559 *
1560 * NB: do not call this directly unless you are prepared to deal with
1561 * concurrent-update conditions. Use simple_table_tuple_update instead.
1562 *
1563 * Input parameters:
1564 * rel - table to be modified (caller must hold suitable lock)
1565 * otid - TID of old tuple to be replaced
1566 * cid - update command ID (used for visibility test, and stored into
1567 * cmax/cmin if successful)
1568 * options - bitmask of options. No values are currently recognized.
1569 * crosscheck - if not InvalidSnapshot, also check old tuple against this
1570 * options - These allow the caller to specify options that may change the
1571 * behavior of the AM. The AM will ignore options that it does not support.
1572 * TABLE_UPDATE_WAIT -- set if should wait for any conflicting update to
1573 * commit/abort
1574 * TABLE_UPDATE_NO_LOGICAL -- force-disables the emitting of logical
1575 * decoding information for the tuple.
1576 *
1577 * Output parameters:
1578 * slot - newly constructed tuple data to store
1579 * tmfd - filled in failure cases (see below)
1580 * lockmode - filled with lock mode acquired on tuple
1581 * update_indexes - in success cases this is set if new index entries
1582 * are required for this tuple; see TU_UpdateIndexes
1583 *
1584 * Normal, successful return value is TM_Ok, which means we did actually
1585 * update it. Failure return codes are TM_SelfModified, TM_Updated, and
1586 * TM_BeingModified (the last only possible if wait == false).
1587 *
1588 * On success, the slot's tts_tid and tts_tableOid are updated to match the new
1589 * stored tuple; in particular, slot->tts_tid is set to the TID where the
1590 * new tuple was inserted, and its HEAP_ONLY_TUPLE flag is set iff a HOT
1591 * update was done. However, any TOAST changes in the new tuple's
1592 * data are not reflected into *newtup.
1593 *
1594 * In the failure cases, the routine fills *tmfd with the tuple's t_ctid,
1595 * t_xmax, and, if possible, t_cmax. See comments for struct TM_FailureData
1596 * for additional info.
1597 */
1598static inline TM_Result
1601 Snapshot snapshot, Snapshot crosscheck,
1602 bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode,
1604{
1605 return rel->rd_tableam->tuple_update(rel, otid, slot,
1606 cid, options, snapshot, crosscheck,
1607 wait, tmfd,
1608 lockmode, update_indexes);
1609}
1610
1611/*
1612 * Lock a tuple in the specified mode.
1613 *
1614 * Input parameters:
1615 * rel: relation containing tuple (caller must hold suitable lock)
1616 * tid: TID of tuple to lock (updated if an update chain was followed)
1617 * snapshot: snapshot to use for visibility determinations
1618 * cid: current command ID (used for visibility test, and stored into
1619 * tuple's cmax if lock is successful)
1620 * mode: lock mode desired
1621 * wait_policy: what to do if tuple lock is not available
1622 * flags:
1623 * If TUPLE_LOCK_FLAG_LOCK_UPDATE_IN_PROGRESS, follow the update chain to
1624 * also lock descendant tuples if lock modes don't conflict.
1625 * If TUPLE_LOCK_FLAG_FIND_LAST_VERSION, follow the update chain and lock
1626 * latest version.
1627 *
1628 * Output parameters:
1629 * *slot: contains the target tuple
1630 * *tmfd: filled in failure cases (see below)
1631 *
1632 * Function result may be:
1633 * TM_Ok: lock was successfully acquired
1634 * TM_Invisible: lock failed because tuple was never visible to us
1635 * TM_SelfModified: lock failed because tuple updated by self
1636 * TM_Updated: lock failed because tuple updated by other xact
1637 * TM_Deleted: lock failed because tuple deleted by other xact
1638 * TM_WouldBlock: lock couldn't be acquired and wait_policy is skip
1639 *
1640 * In the failure cases other than TM_Invisible and TM_Deleted, the routine
1641 * fills *tmfd with the tuple's t_ctid, t_xmax, and, if possible, t_cmax.
1642 * Additionally, in both success and failure cases, tmfd->traversed is set if
1643 * an update chain was followed. See comments for struct TM_FailureData for
1644 * additional info.
1645 */
1646static inline TM_Result
1650 TM_FailureData *tmfd)
1651{
1652 return rel->rd_tableam->tuple_lock(rel, tid, snapshot, slot,
1654 flags, tmfd);
1655}
1656
1657/*
1658 * Perform operations necessary to complete insertions made via
1659 * tuple_insert and multi_insert with a BulkInsertState specified.
1660 */
1661static inline void
1663{
1664 /* optional callback */
1667}
1668
1669
1670/* ------------------------------------------------------------------------
1671 * DDL related functionality.
1672 * ------------------------------------------------------------------------
1673 */
1674
1675/*
1676 * Create storage for `rel` in `newrlocator`, with persistence set to
1677 * `persistence`.
1678 *
1679 * This is used both during relation creation and various DDL operations to
1680 * create new rel storage that can be filled from scratch. When creating
1681 * new storage for an existing relfilelocator, this should be called before the
1682 * relcache entry has been updated.
1683 *
1684 * *freezeXid, *minmulti are set to the xid / multixact horizon for the table
1685 * that pg_class.{relfrozenxid, relminmxid} have to be set to.
1686 */
1687static inline void
1690 char persistence,
1693{
1695 persistence, freezeXid,
1696 minmulti);
1697}
1698
1699/*
1700 * Remove all table contents from `rel`, in a non-transactional manner.
1701 * Non-transactional meaning that there's no need to support rollbacks. This
1702 * commonly only is used to perform truncations for relation storage created in
1703 * the current transaction.
1704 */
1705static inline void
1707{
1709}
1710
1711/*
1712 * Copy data from `rel` into the new relfilelocator `newrlocator`. The new
1713 * relfilelocator may not have storage associated before this function is
1714 * called. This is only supposed to be used for low level operations like
1715 * changing a relation's tablespace.
1716 */
1717static inline void
1719{
1721}
1722
1723/*
1724 * Copy data from `OldTable` into `NewTable`, as part of a CLUSTER or VACUUM
1725 * FULL.
1726 *
1727 * Additional Input parameters:
1728 * - use_sort - if true, the table contents are sorted appropriate for
1729 * `OldIndex`; if false and OldIndex is not InvalidOid, the data is copied
1730 * in that index's order; if false and OldIndex is InvalidOid, no sorting is
1731 * performed
1732 * - OldIndex - see use_sort
1733 * - OldestXmin - computed by vacuum_get_cutoffs(), even when
1734 * not needed for the relation's AM
1735 * - *xid_cutoff - ditto
1736 * - *multi_cutoff - ditto
1737 * - snapshot - if != NULL, ignore data changes done by transactions that this
1738 * (MVCC) snapshot considers still in-progress or in the future.
1739 *
1740 * Output parameters:
1741 * - *xid_cutoff - rel's new relfrozenxid value, may be invalid
1742 * - *multi_cutoff - rel's new relminmxid value, may be invalid
1743 * - *tups_vacuumed - stats, for logging, if appropriate for AM
1744 * - *tups_recently_dead - stats, for logging, if appropriate for AM
1745 */
1746static inline void
1749 bool use_sort,
1750 TransactionId OldestXmin,
1751 Snapshot snapshot,
1754 double *num_tuples,
1755 double *tups_vacuumed,
1756 double *tups_recently_dead)
1757{
1758 OldTable->rd_tableam->relation_copy_for_cluster(OldTable, NewTable, OldIndex,
1759 use_sort, OldestXmin,
1760 snapshot,
1762 num_tuples, tups_vacuumed,
1764}
1765
1766/*
1767 * Perform VACUUM on the relation. The VACUUM can be triggered by a user or by
1768 * autovacuum. The specific actions performed by the AM will depend heavily on
1769 * the individual AM.
1770 *
1771 * On entry a transaction needs to already been established, and the
1772 * table is locked with a ShareUpdateExclusive lock.
1773 *
1774 * Note that neither VACUUM FULL (and CLUSTER), nor ANALYZE go through this
1775 * routine, even if (for ANALYZE) it is part of the same VACUUM command.
1776 */
1777static inline void
1779 BufferAccessStrategy bstrategy)
1780{
1781 rel->rd_tableam->relation_vacuum(rel, params, bstrategy);
1782}
1783
1784/*
1785 * Prepare to analyze the next block in the read stream. The scan needs to
1786 * have been started with table_beginscan_analyze(). Note that this routine
1787 * might acquire resources like locks that are held until
1788 * table_scan_analyze_next_tuple() returns false.
1789 *
1790 * Returns false if block is unsuitable for sampling, true otherwise.
1791 */
1792static inline bool
1794{
1795 return scan->rs_rd->rd_tableam->scan_analyze_next_block(scan, stream);
1796}
1797
1798/*
1799 * Iterate over tuples in the block selected with
1800 * table_scan_analyze_next_block() (which needs to have returned true, and
1801 * this routine may not have returned false for the same block before). If a
1802 * tuple that's suitable for sampling is found, true is returned and a tuple
1803 * is stored in `slot`.
1804 *
1805 * *liverows and *deadrows are incremented according to the encountered
1806 * tuples.
1807 */
1808static inline bool
1810 double *liverows, double *deadrows,
1811 TupleTableSlot *slot)
1812{
1813 return scan->rs_rd->rd_tableam->scan_analyze_next_tuple(scan,
1815 slot);
1816}
1817
1818/*
1819 * table_index_build_scan - scan the table to find tuples to be indexed
1820 *
1821 * This is called back from an access-method-specific index build procedure
1822 * after the AM has done whatever setup it needs. The parent table relation
1823 * is scanned to find tuples that should be entered into the index. Each
1824 * such tuple is passed to the AM's callback routine, which does the right
1825 * things to add it to the new index. After we return, the AM's index
1826 * build procedure does whatever cleanup it needs.
1827 *
1828 * The total count of live tuples is returned. This is for updating pg_class
1829 * statistics. (It's annoying not to be able to do that here, but we want to
1830 * merge that update with others; see index_update_stats.) Note that the
1831 * index AM itself must keep track of the number of index tuples; we don't do
1832 * so here because the AM might reject some of the tuples for its own reasons,
1833 * such as being unable to store NULLs.
1834 *
1835 * If 'progress', the PROGRESS_SCAN_BLOCKS_TOTAL counter is updated when
1836 * starting the scan, and PROGRESS_SCAN_BLOCKS_DONE is updated as we go along.
1837 *
1838 * A side effect is to set indexInfo->ii_BrokenHotChain to true if we detect
1839 * any potentially broken HOT chains. Currently, we set this if there are any
1840 * RECENTLY_DEAD or DELETE_IN_PROGRESS entries in a HOT chain, without trying
1841 * very hard to detect whether they're really incompatible with the chain tip.
1842 * This only really makes sense for heap AM, it might need to be generalized
1843 * for other AMs later.
1844 */
1845static inline double
1849 bool allow_sync,
1850 bool progress,
1852 void *callback_state,
1853 TableScanDesc scan)
1854{
1855 return table_rel->rd_tableam->index_build_range_scan(table_rel,
1856 index_rel,
1857 index_info,
1858 allow_sync,
1859 false,
1860 progress,
1861 0,
1863 callback,
1864 callback_state,
1865 scan);
1866}
1867
1868/*
1869 * As table_index_build_scan(), except that instead of scanning the complete
1870 * table, only the given number of blocks are scanned. Scan to end-of-rel can
1871 * be signaled by passing InvalidBlockNumber as numblocks. Note that
1872 * restricting the range to scan cannot be done when requesting syncscan.
1873 *
1874 * When "anyvisible" mode is requested, all tuples visible to any transaction
1875 * are indexed and counted as live, including those inserted or deleted by
1876 * transactions that are still in progress.
1877 */
1878static inline double
1882 bool allow_sync,
1883 bool anyvisible,
1884 bool progress,
1888 void *callback_state,
1889 TableScanDesc scan)
1890{
1891 return table_rel->rd_tableam->index_build_range_scan(table_rel,
1892 index_rel,
1893 index_info,
1894 allow_sync,
1895 anyvisible,
1896 progress,
1898 numblocks,
1899 callback,
1900 callback_state,
1901 scan);
1902}
1903
1904/*
1905 * table_index_validate_scan - second table scan for concurrent index build
1906 *
1907 * See validate_index() for an explanation.
1908 */
1909static inline void
1913 Snapshot snapshot,
1915{
1916 table_rel->rd_tableam->index_validate_scan(table_rel,
1917 index_rel,
1918 index_info,
1919 snapshot,
1920 state);
1921}
1922
1923
1924/* ----------------------------------------------------------------------------
1925 * Miscellaneous functionality
1926 * ----------------------------------------------------------------------------
1927 */
1928
1929/*
1930 * Return the current size of `rel` in bytes. If `forkNumber` is
1931 * InvalidForkNumber, return the relation's overall size, otherwise the size
1932 * for the indicated fork.
1933 *
1934 * Note that the overall size might not be the equivalent of the sum of sizes
1935 * for the individual forks for some AMs, e.g. because the AMs storage does
1936 * not neatly map onto the builtin types of forks.
1937 */
1938static inline uint64
1940{
1942}
1943
1944/*
1945 * table_relation_needs_toast_table - does this relation need a toast table?
1946 */
1947static inline bool
1949{
1951}
1952
1953/*
1954 * Return the OID of the AM that should be used to implement the TOAST table
1955 * for this relation.
1956 */
1957static inline Oid
1959{
1961}
1962
1963/*
1964 * Fetch all or part of a TOAST value from a TOAST table.
1965 *
1966 * If this AM is never used to implement a TOAST table, then this callback
1967 * is not needed. But, if toasted values are ever stored in a table of this
1968 * type, then you will need this callback.
1969 *
1970 * toastrel is the relation in which the toasted value is stored.
1971 *
1972 * valueid identifies which toast value is to be fetched. For the heap,
1973 * this corresponds to the values stored in the chunk_id column.
1974 *
1975 * attrsize is the total size of the toast value to be fetched.
1976 *
1977 * sliceoffset is the offset within the toast value of the first byte that
1978 * should be fetched.
1979 *
1980 * slicelength is the number of bytes from the toast value that should be
1981 * fetched.
1982 *
1983 * result is caller-allocated space into which the fetched bytes should be
1984 * stored.
1985 */
1986static inline void
1990{
1991 toastrel->rd_tableam->relation_fetch_toast_slice(toastrel, valueid,
1992 attrsize,
1994 result);
1995}
1996
1997
1998/* ----------------------------------------------------------------------------
1999 * Planner related functionality
2000 * ----------------------------------------------------------------------------
2001 */
2002
2003/*
2004 * Estimate the current size of the relation, as an AM specific workhorse for
2005 * estimate_rel_size(). Look there for an explanation of the parameters.
2006 */
2007static inline void
2009 BlockNumber *pages, double *tuples,
2010 double *allvisfrac)
2011{
2013 allvisfrac);
2014}
2015
2016
2017/* ----------------------------------------------------------------------------
2018 * Executor related functionality
2019 * ----------------------------------------------------------------------------
2020 */
2021
2022/*
2023 * Fetch / check / return tuples as part of a bitmap table scan. `scan` needs
2024 * to have been started via table_beginscan_bm(). Fetch the next tuple of a
2025 * bitmap table scan into `slot` and return true if a visible tuple was found,
2026 * false otherwise.
2027 *
2028 * `recheck` is set by the table AM to indicate whether or not the tuple in
2029 * `slot` should be rechecked. Tuples from lossy pages will always need to be
2030 * rechecked, but some non-lossy pages' tuples may also require recheck.
2031 *
2032 * `lossy_pages` is incremented if the block's representation in the bitmap is
2033 * lossy; otherwise, `exact_pages` is incremented.
2034 */
2035static inline bool
2037 TupleTableSlot *slot,
2038 bool *recheck,
2039 uint64 *lossy_pages,
2040 uint64 *exact_pages)
2041{
2042 return scan->rs_rd->rd_tableam->scan_bitmap_next_tuple(scan,
2043 slot,
2044 recheck,
2045 lossy_pages,
2046 exact_pages);
2047}
2048
2049/*
2050 * Prepare to fetch tuples from the next block in a sample scan. Returns false
2051 * if the sample scan is finished, true otherwise. `scan` needs to have been
2052 * started via table_beginscan_sampling().
2053 *
2054 * This will call the TsmRoutine's NextSampleBlock() callback if necessary
2055 * (i.e. NextSampleBlock is not NULL), or perform a sequential scan over the
2056 * underlying relation.
2057 */
2058static inline bool
2061{
2062 return scan->rs_rd->rd_tableam->scan_sample_next_block(scan, scanstate);
2063}
2064
2065/*
2066 * Fetch the next sample tuple into `slot` and return true if a visible tuple
2067 * was found, false otherwise. table_scan_sample_next_block() needs to
2068 * previously have selected a block (i.e. returned true), and no previous
2069 * table_scan_sample_next_tuple() for the same block may have returned false.
2070 *
2071 * This will call the TsmRoutine's NextSampleTuple() callback.
2072 */
2073static inline bool
2076 TupleTableSlot *slot)
2077{
2078 return scan->rs_rd->rd_tableam->scan_sample_next_tuple(scan, scanstate,
2079 slot);
2080}
2081
2082
2083/* ----------------------------------------------------------------------------
2084 * Functions to make modifications a bit simpler.
2085 * ----------------------------------------------------------------------------
2086 */
2087
2090 Snapshot snapshot);
2092 TupleTableSlot *slot, Snapshot snapshot,
2094
2095
2096/* ----------------------------------------------------------------------------
2097 * Helper functions to implement parallel scans for block oriented AMs.
2098 * ----------------------------------------------------------------------------
2099 */
2100
2112 BlockNumber startblock,
2114
2115
2116/* ----------------------------------------------------------------------------
2117 * Helper functions to implement relation sizing for block oriented AMs.
2118 * ----------------------------------------------------------------------------
2119 */
2120
2124 BlockNumber *pages,
2125 double *tuples,
2126 double *allvisfrac,
2129
2130/* ----------------------------------------------------------------------------
2131 * Functions in tableamapi.c
2132 * ----------------------------------------------------------------------------
2133 */
2134
2135extern const TableAmRoutine *GetTableAmRoutine(Oid amhandler);
2136
2137/* ----------------------------------------------------------------------------
2138 * Functions in heapam_handler.c
2139 * ----------------------------------------------------------------------------
2140 */
2141
2142extern const TableAmRoutine *GetHeapamTableAmRoutine(void);
2143
2144#endif /* TABLEAM_H */
uint32 BlockNumber
Definition block.h:31
#define InvalidBlockNumber
Definition block.h:33
static Datum values[MAXATTR]
Definition bootstrap.c:190
uint8_t uint8
Definition c.h:622
#define Assert(condition)
Definition c.h:943
TransactionId MultiXactId
Definition c.h:746
int16_t int16
Definition c.h:619
int32_t int32
Definition c.h:620
uint64_t uint64
Definition c.h:625
#define unlikely(x)
Definition c.h:438
uint32_t uint32
Definition c.h:624
uint32 CommandId
Definition c.h:750
uint32 TransactionId
Definition c.h:736
size_t Size
Definition c.h:689
uint32 result
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
LockWaitPolicy
Definition lockoptions.h:38
LockTupleMode
Definition lockoptions.h:51
NodeTag
Definition nodes.h:27
uint16 OffsetNumber
Definition off.h:24
static PgChecksumMode mode
const void * data
static int progress
Definition pgbench.c:262
uint64_t Datum
Definition postgres.h:70
unsigned int Oid
static int fb(int x)
#define RelationGetRelid(relation)
Definition rel.h:516
ForkNumber
Definition relpath.h:56
struct TableScanDescData * TableScanDesc
Definition relscan.h:74
ScanDirection
Definition sdir.h:25
@ BackwardScanDirection
Definition sdir.h:26
@ ForwardScanDirection
Definition sdir.h:28
Definition pg_list.h:54
const struct TableAmRoutine * rd_tableam
Definition rel.h:189
TransactionId xmax
Definition tableam.h:172
CommandId cmax
Definition tableam.h:173
ItemPointerData ctid
Definition tableam.h:171
TM_IndexStatus * status
Definition tableam.h:276
int bottomupfreespace
Definition tableam.h:271
Relation irel
Definition tableam.h:268
TM_IndexDelete * deltids
Definition tableam.h:275
BlockNumber iblknum
Definition tableam.h:269
ItemPointerData tid
Definition tableam.h:234
bool knowndeletable
Definition tableam.h:241
int16 freespace
Definition tableam.h:245
OffsetNumber idxoffnum
Definition tableam.h:240
Size(* parallelscan_initialize)(Relation rel, ParallelTableScanDesc pscan)
Definition tableam.h:432
void(* relation_copy_data)(Relation rel, const RelFileLocator *newrlocator)
Definition tableam.h:660
TM_Result(* tuple_update)(Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes)
Definition tableam.h:579
void(* index_fetch_reset)(struct IndexFetchTableData *data)
Definition tableam.h:465
TableScanDesc(* scan_begin)(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, ParallelTableScanDesc pscan, uint32 flags)
Definition tableam.h:360
void(* tuple_complete_speculative)(Relation rel, TupleTableSlot *slot, uint32 specToken, bool succeeded)
Definition tableam.h:559
bool(* scan_analyze_next_tuple)(TableScanDesc scan, double *liverows, double *deadrows, TupleTableSlot *slot)
Definition tableam.h:723
void(* parallelscan_reinitialize)(Relation rel, ParallelTableScanDesc pscan)
Definition tableam.h:439
bool(* scan_sample_next_tuple)(TableScanDesc scan, SampleScanState *scanstate, TupleTableSlot *slot)
Definition tableam.h:877
bool(* scan_sample_next_block)(TableScanDesc scan, SampleScanState *scanstate)
Definition tableam.h:861
void(* tuple_get_latest_tid)(TableScanDesc scan, ItemPointer tid)
Definition tableam.h:524
void(* tuple_insert)(Relation rel, TupleTableSlot *slot, CommandId cid, uint32 options, BulkInsertStateData *bistate)
Definition tableam.h:546
bool(* scan_bitmap_next_tuple)(TableScanDesc scan, TupleTableSlot *slot, bool *recheck, uint64 *lossy_pages, uint64 *exact_pages)
Definition tableam.h:830
bool(* scan_getnextslot_tidrange)(TableScanDesc scan, ScanDirection direction, TupleTableSlot *slot)
Definition tableam.h:412
void(* relation_estimate_size)(Relation rel, int32 *attr_widths, BlockNumber *pages, double *tuples, double *allvisfrac)
Definition tableam.h:808
bool(* relation_needs_toast_table)(Relation rel)
Definition tableam.h:772
bool(* tuple_tid_valid)(TableScanDesc scan, ItemPointer tid)
Definition tableam.h:517
void(* multi_insert)(Relation rel, TupleTableSlot **slots, int nslots, CommandId cid, uint32 options, BulkInsertStateData *bistate)
Definition tableam.h:565
void(* scan_end)(TableScanDesc scan)
Definition tableam.h:370
uint64(* relation_size)(Relation rel, ForkNumber forkNumber)
Definition tableam.h:762
TM_Result(* tuple_lock)(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot, CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy, uint8 flags, TM_FailureData *tmfd)
Definition tableam.h:592
void(* relation_fetch_toast_slice)(Relation toastrel, Oid valueid, int32 attrsize, int32 sliceoffset, int32 slicelength, varlena *result)
Definition tableam.h:786
void(* relation_copy_for_cluster)(Relation OldTable, Relation NewTable, Relation OldIndex, bool use_sort, TransactionId OldestXmin, Snapshot snapshot, TransactionId *xid_cutoff, MultiXactId *multi_cutoff, double *num_tuples, double *tups_vacuumed, double *tups_recently_dead)
Definition tableam.h:664
void(* tuple_insert_speculative)(Relation rel, TupleTableSlot *slot, CommandId cid, uint32 options, BulkInsertStateData *bistate, uint32 specToken)
Definition tableam.h:551
void(* relation_nontransactional_truncate)(Relation rel)
Definition tableam.h:652
TM_Result(* tuple_delete)(Relation rel, ItemPointer tid, CommandId cid, uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd)
Definition tableam.h:569
bool(* tuple_fetch_row_version)(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot)
Definition tableam.h:509
struct IndexFetchTableData *(* index_fetch_begin)(Relation rel, uint32 flags)
Definition tableam.h:459
Oid(* relation_toast_am)(Relation rel)
Definition tableam.h:779
bool(* scan_analyze_next_block)(TableScanDesc scan, ReadStream *stream)
Definition tableam.h:712
Size(* parallelscan_estimate)(Relation rel)
Definition tableam.h:425
void(* relation_set_new_filelocator)(Relation rel, const RelFileLocator *newrlocator, char persistence, TransactionId *freezeXid, MultiXactId *minmulti)
Definition tableam.h:638
void(* scan_rescan)(TableScanDesc scan, ScanKeyData *key, bool set_params, bool allow_strat, bool allow_sync, bool allow_pagemode)
Definition tableam.h:376
void(* scan_set_tidrange)(TableScanDesc scan, ItemPointer mintid, ItemPointer maxtid)
Definition tableam.h:404
TransactionId(* index_delete_tuples)(Relation rel, TM_IndexDeleteOp *delstate)
Definition tableam.h:536
void(* index_fetch_end)(struct IndexFetchTableData *data)
Definition tableam.h:470
bool(* index_fetch_tuple)(struct IndexFetchTableData *scan, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot, bool *call_again, bool *all_dead)
Definition tableam.h:492
double(* index_build_range_scan)(Relation table_rel, Relation index_rel, IndexInfo *index_info, bool allow_sync, bool anyvisible, bool progress, BlockNumber start_blockno, BlockNumber numblocks, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)
Definition tableam.h:729
NodeTag type
Definition tableam.h:324
void(* index_validate_scan)(Relation table_rel, Relation index_rel, IndexInfo *index_info, Snapshot snapshot, ValidateIndexState *state)
Definition tableam.h:742
void(* finish_bulk_insert)(Relation rel, uint32 options)
Definition tableam.h:614
void(* relation_vacuum)(Relation rel, const VacuumParams *params, BufferAccessStrategy bstrategy)
Definition tableam.h:691
bool(* scan_getnextslot)(TableScanDesc scan, ScanDirection direction, TupleTableSlot *slot)
Definition tableam.h:383
bool(* tuple_satisfies_snapshot)(Relation rel, TupleTableSlot *slot, Snapshot snapshot)
Definition tableam.h:531
Relation rs_rd
Definition relscan.h:36
Definition type.h:96
Definition c.h:776
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition tableam.c:92
@ SO_NONE
Definition tableam.h:49
static void table_rescan_tidrange(TableScanDesc sscan, ItemPointer mintid, ItemPointer maxtid)
Definition tableam.h:1141
TU_UpdateIndexes
Definition tableam.h:133
@ TU_Summarizing
Definition tableam.h:141
@ TU_All
Definition tableam.h:138
@ TU_None
Definition tableam.h:135
static double table_index_build_range_scan(Relation table_rel, Relation index_rel, IndexInfo *index_info, bool allow_sync, bool anyvisible, bool progress, BlockNumber start_blockno, BlockNumber numblocks, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)
Definition tableam.h:1880
static void table_endscan(TableScanDesc scan)
Definition tableam.h:1061
void simple_table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, Snapshot snapshot, TU_UpdateIndexes *update_indexes)
Definition tableam.c:361
static TableScanDesc table_beginscan_sampling(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, bool allow_strat, bool allow_sync, bool allow_pagemode, uint32 flags)
Definition tableam.h:1011
bool table_index_fetch_tuple_check(Relation rel, ItemPointer tid, Snapshot snapshot, bool *all_dead)
Definition tableam.c:242
Size table_block_parallelscan_initialize(Relation rel, ParallelTableScanDesc pscan)
Definition tableam.c:414
static void table_index_validate_scan(Relation table_rel, Relation index_rel, IndexInfo *index_info, Snapshot snapshot, ValidateIndexState *state)
Definition tableam.h:1911
static void table_index_fetch_reset(struct IndexFetchTableData *scan)
Definition tableam.h:1266
static uint64 table_relation_size(Relation rel, ForkNumber forkNumber)
Definition tableam.h:1940
static bool table_scan_sample_next_block(TableScanDesc scan, SampleScanState *scanstate)
Definition tableam.h:2060
TM_Result
Definition tableam.h:95
@ TM_Ok
Definition tableam.h:100
@ TM_BeingModified
Definition tableam.h:122
@ TM_Deleted
Definition tableam.h:115
@ TM_WouldBlock
Definition tableam.h:125
@ TM_Updated
Definition tableam.h:112
@ TM_SelfModified
Definition tableam.h:106
@ TM_Invisible
Definition tableam.h:103
TableScanDesc table_beginscan_parallel_tidrange(Relation relation, ParallelTableScanDesc pscan, uint32 flags)
Definition tableam.c:193
static bool table_scan_bitmap_next_tuple(TableScanDesc scan, TupleTableSlot *slot, bool *recheck, uint64 *lossy_pages, uint64 *exact_pages)
Definition tableam.h:2037
static TM_Result table_tuple_lock(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot, CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy, uint8 flags, TM_FailureData *tmfd)
Definition tableam.h:1648
void simple_table_tuple_insert(Relation rel, TupleTableSlot *slot)
Definition tableam.c:302
static bool table_tuple_tid_valid(TableScanDesc scan, ItemPointer tid)
Definition tableam.h:1370
static TableScanDesc table_beginscan_bm(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, uint32 flags)
Definition tableam.h:992
static void table_rescan_set_params(TableScanDesc scan, ScanKeyData *key, bool allow_strat, bool allow_sync, bool allow_pagemode)
Definition tableam.h:1084
static void table_tuple_insert_speculative(Relation rel, TupleTableSlot *slot, CommandId cid, uint32 options, BulkInsertStateData *bistate, uint32 specToken)
Definition tableam.h:1477
static bool table_scan_analyze_next_block(TableScanDesc scan, ReadStream *stream)
Definition tableam.h:1794
static bool table_relation_needs_toast_table(Relation rel)
Definition tableam.h:1949
static TableScanDesc table_beginscan_common(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, ParallelTableScanDesc pscan, uint32 flags, uint32 user_flags)
Definition tableam.h:917
TableScanDesc table_beginscan_parallel(Relation relation, ParallelTableScanDesc pscan, uint32 flags)
Definition tableam.c:166
static void table_tuple_complete_speculative(Relation rel, TupleTableSlot *slot, uint32 specToken, bool succeeded)
Definition tableam.h:1491
static void table_index_fetch_end(struct IndexFetchTableData *scan)
Definition tableam.h:1275
static TableScanDesc table_beginscan_analyze(Relation rel)
Definition tableam.h:1049
const TableAmRoutine * GetTableAmRoutine(Oid amhandler)
Definition tableamapi.c:27
void table_tuple_get_latest_tid(TableScanDesc scan, ItemPointer tid)
Definition tableam.c:269
static void table_rescan(TableScanDesc scan, ScanKeyData *key)
Definition tableam.h:1070
static bool table_index_fetch_tuple(struct IndexFetchTableData *scan, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot, bool *call_again, bool *all_dead)
Definition tableam.h:1305
const TableAmRoutine * GetHeapamTableAmRoutine(void)
void simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot)
Definition tableam.c:316
static void table_relation_fetch_toast_slice(Relation toastrel, Oid valueid, int32 attrsize, int32 sliceoffset, int32 slicelength, varlena *result)
Definition tableam.h:1988
static TableScanDesc table_beginscan_tidrange(Relation rel, Snapshot snapshot, ItemPointer mintid, ItemPointer maxtid, uint32 flags)
Definition tableam.h:1119
void table_block_parallelscan_reinitialize(Relation rel, ParallelTableScanDesc pscan)
Definition tableam.c:433
void(* IndexBuildCallback)(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
Definition tableam.h:303
uint64 table_block_relation_size(Relation rel, ForkNumber forkNumber)
Definition tableam.c:681
static void table_relation_copy_for_cluster(Relation OldTable, Relation NewTable, Relation OldIndex, bool use_sort, TransactionId OldestXmin, Snapshot snapshot, TransactionId *xid_cutoff, MultiXactId *multi_cutoff, double *num_tuples, double *tups_vacuumed, double *tups_recently_dead)
Definition tableam.h:1748
static void table_relation_set_new_filelocator(Relation rel, const RelFileLocator *newrlocator, char persistence, TransactionId *freezeXid, MultiXactId *minmulti)
Definition tableam.h:1689
static bool table_scan_analyze_next_tuple(TableScanDesc scan, double *liverows, double *deadrows, TupleTableSlot *slot)
Definition tableam.h:1810
static bool table_scan_getnextslot_tidrange(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
Definition tableam.h:1157
static Oid table_relation_toast_am(Relation rel)
Definition tableam.h:1959
static void table_finish_bulk_insert(Relation rel, uint32 options)
Definition tableam.h:1663
static bool table_scan_sample_next_tuple(TableScanDesc scan, SampleScanState *scanstate, TupleTableSlot *slot)
Definition tableam.h:2075
static void table_tuple_insert(Relation rel, TupleTableSlot *slot, CommandId cid, uint32 options, BulkInsertStateData *bistate)
Definition tableam.h:1458
Size table_parallelscan_estimate(Relation rel, Snapshot snapshot)
Definition tableam.c:131
static void table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, CommandId cid, uint32 options, BulkInsertStateData *bistate)
Definition tableam.h:1513
#define SO_INTERNAL_FLAGS
Definition tableam.h:84
static TableScanDesc table_beginscan(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, uint32 flags)
Definition tableam.h:943
static double table_index_build_scan(Relation table_rel, Relation index_rel, IndexInfo *index_info, bool allow_sync, bool progress, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)
Definition tableam.h:1847
static void table_relation_copy_data(Relation rel, const RelFileLocator *newrlocator)
Definition tableam.h:1719
static TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes)
Definition tableam.h:1600
static TableScanDesc table_beginscan_strat(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, bool allow_strat, bool allow_sync)
Definition tableam.h:968
TableScanDesc table_beginscan_catalog(Relation relation, int nkeys, ScanKeyData *key)
Definition tableam.c:113
Size table_block_parallelscan_estimate(Relation rel)
Definition tableam.c:408
static void table_relation_estimate_size(Relation rel, int32 *attr_widths, BlockNumber *pages, double *tuples, double *allvisfrac)
Definition tableam.h:2009
static bool table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
Definition tableam.h:1096
void table_block_parallelscan_startblock_init(Relation rel, ParallelBlockTableScanWorker pbscanwork, ParallelBlockTableScanDesc pbscan, BlockNumber startblock, BlockNumber numblocks)
Definition tableam.c:453
static IndexFetchTableData * table_index_fetch_begin(Relation rel, uint32 flags)
Definition tableam.h:1246
static TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd)
Definition tableam.h:1549
static bool table_tuple_satisfies_snapshot(Relation rel, TupleTableSlot *slot, Snapshot snapshot)
Definition tableam.h:1391
static TransactionId table_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate)
Definition tableam.h:1412
static void table_relation_nontransactional_truncate(Relation rel)
Definition tableam.h:1707
static void table_relation_vacuum(Relation rel, const VacuumParams *params, BufferAccessStrategy bstrategy)
Definition tableam.h:1779
void table_parallelscan_initialize(Relation rel, ParallelTableScanDesc pscan, Snapshot snapshot)
Definition tableam.c:146
static bool table_tuple_fetch_row_version(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot)
Definition tableam.h:1344
static void table_parallelscan_reinitialize(Relation rel, ParallelTableScanDesc pscan)
Definition tableam.h:1226
static TableScanDesc table_beginscan_tid(Relation rel, Snapshot snapshot)
Definition tableam.h:1035
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition tableam.c:59
BlockNumber table_block_parallelscan_nextpage(Relation rel, ParallelBlockTableScanWorker pbscanwork, ParallelBlockTableScanDesc pbscan)
Definition tableam.c:548
void table_block_relation_estimate_size(Relation rel, int32 *attr_widths, BlockNumber *pages, double *tuples, double *allvisfrac, Size overhead_bytes_per_tuple, Size usable_bytes_per_page)
Definition tableam.c:718
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
#define TransactionIdIsValid(xid)
Definition transam.h:41
bool bsysscan
Definition xact.c:102
TransactionId CheckXidAlive
Definition xact.c:101

◆ TABLE_DELETE_CHANGING_PARTITION

#define TABLE_DELETE_CHANGING_PARTITION   (1 << 0)

Definition at line 289 of file tableam.h.

◆ TABLE_DELETE_NO_LOGICAL

#define TABLE_DELETE_NO_LOGICAL   (1 << 1)

Definition at line 290 of file tableam.h.

◆ TABLE_INSERT_FROZEN

#define TABLE_INSERT_FROZEN   0x0004

Definition at line 285 of file tableam.h.

◆ TABLE_INSERT_NO_LOGICAL

#define TABLE_INSERT_NO_LOGICAL   0x0008

Definition at line 286 of file tableam.h.

◆ TABLE_INSERT_SKIP_FSM

#define TABLE_INSERT_SKIP_FSM   0x0002

Definition at line 284 of file tableam.h.

◆ TABLE_UPDATE_NO_LOGICAL

#define TABLE_UPDATE_NO_LOGICAL   (1 << 0)

Definition at line 293 of file tableam.h.

◆ TUPLE_LOCK_FLAG_FIND_LAST_VERSION

#define TUPLE_LOCK_FLAG_FIND_LAST_VERSION   (1 << 1)

Definition at line 299 of file tableam.h.

◆ TUPLE_LOCK_FLAG_LOCK_UPDATE_IN_PROGRESS

#define TUPLE_LOCK_FLAG_LOCK_UPDATE_IN_PROGRESS   (1 << 0)

Definition at line 297 of file tableam.h.

Typedef Documentation

◆ BulkInsertStateData

Definition at line 37 of file tableam.h.

◆ IndexBuildCallback

typedef void(* IndexBuildCallback) (Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)

Definition at line 303 of file tableam.h.

◆ IndexInfo

Definition at line 38 of file tableam.h.

◆ SampleScanState

Definition at line 39 of file tableam.h.

◆ ScanKeyData

Definition at line 40 of file tableam.h.

◆ ScanOptions

◆ TableAmRoutine

◆ TM_FailureData

◆ TM_IndexDelete

◆ TM_IndexDeleteOp

◆ TM_IndexStatus

◆ TM_Result

◆ TU_UpdateIndexes

◆ VacuumParams

Definition at line 42 of file tableam.h.

◆ ValidateIndexState

Definition at line 41 of file tableam.h.

Enumeration Type Documentation

◆ ScanOptions

Enumerator
SO_NONE 
SO_TYPE_SEQSCAN 
SO_TYPE_BITMAPSCAN 
SO_TYPE_SAMPLESCAN 
SO_TYPE_TIDSCAN 
SO_TYPE_TIDRANGESCAN 
SO_TYPE_ANALYZE 
SO_ALLOW_STRAT 
SO_ALLOW_SYNC 
SO_ALLOW_PAGEMODE 
SO_TEMP_SNAPSHOT 
SO_HINT_REL_READ_ONLY 
SO_SCAN_INSTRUMENT 

Definition at line 47 of file tableam.h.

48{
49 SO_NONE = 0,
50
51 /* one of SO_TYPE_* may be specified */
52 SO_TYPE_SEQSCAN = 1 << 0,
53 SO_TYPE_BITMAPSCAN = 1 << 1,
54 SO_TYPE_SAMPLESCAN = 1 << 2,
55 SO_TYPE_TIDSCAN = 1 << 3,
56 SO_TYPE_TIDRANGESCAN = 1 << 4,
57 SO_TYPE_ANALYZE = 1 << 5,
58
59 /* several of SO_ALLOW_* may be specified */
60 /* allow or disallow use of access strategy */
61 SO_ALLOW_STRAT = 1 << 6,
62 /* report location to syncscan logic? */
63 SO_ALLOW_SYNC = 1 << 7,
64 /* verify visibility page-at-a-time? */
65 SO_ALLOW_PAGEMODE = 1 << 8,
66
67 /* unregister snapshot at scan end? */
68 SO_TEMP_SNAPSHOT = 1 << 9,
69
70 /* set if the query doesn't modify the relation */
71 SO_HINT_REL_READ_ONLY = 1 << 10,
72
73 /* collect scan instrumentation */
74 SO_SCAN_INSTRUMENT = 1 << 11,
ScanOptions
Definition tableam.h:48
@ SO_HINT_REL_READ_ONLY
Definition tableam.h:71
@ SO_SCAN_INSTRUMENT
Definition tableam.h:74

◆ TM_Result

Enumerator
TM_Ok 
TM_Invisible 
TM_SelfModified 
TM_Updated 
TM_Deleted 
TM_BeingModified 
TM_WouldBlock 

Definition at line 94 of file tableam.h.

95{
96 /*
97 * Signals that the action succeeded (i.e. update/delete performed, lock
98 * was acquired)
99 */
100 TM_Ok,
101
102 /* The affected tuple wasn't visible to the relevant snapshot */
104
105 /* The affected tuple was already modified by the calling backend */
107
108 /*
109 * The affected tuple was updated by another transaction. This includes
110 * the case where tuple was moved to another partition.
111 */
113
114 /* The affected tuple was deleted by another transaction */
116
117 /*
118 * The affected tuple is currently being modified by another session. This
119 * will only be returned if table_(update/delete/lock_tuple) are
120 * instructed not to wait.
121 */
123
124 /* lock couldn't be acquired, action skipped. Only used by lock_tuple */
126} TM_Result;

◆ TU_UpdateIndexes

Enumerator
TU_None 
TU_All 
TU_Summarizing 

Definition at line 132 of file tableam.h.

133{
134 /* No indexed columns were updated (incl. TID addressing of tuple) */
135 TU_None,
136
137 /* A non-summarizing indexed column was updated, or the TID has changed */
138 TU_All,
139
140 /* Only summarized columns were updated, TID is unchanged */

Function Documentation

◆ GetHeapamTableAmRoutine()

const TableAmRoutine * GetHeapamTableAmRoutine ( void  )
extern

Definition at line 2705 of file heapam_handler.c.

2706{
2707 return &heapam_methods;
2708}
static const TableAmRoutine heapam_methods

References heapam_methods.

Referenced by formrdesc(), and heap_getnext().

◆ GetTableAmRoutine()

const TableAmRoutine * GetTableAmRoutine ( Oid  amhandler)
extern

Definition at line 27 of file tableamapi.c.

28{
29 Datum datum;
30 const TableAmRoutine *routine;
31
32 datum = OidFunctionCall0(amhandler);
33 routine = (const TableAmRoutine *) DatumGetPointer(datum);
34
35 if (routine == NULL || !IsA(routine, TableAmRoutine))
36 elog(ERROR, "table access method handler %u did not return a TableAmRoutine struct",
37 amhandler);
38
39 /*
40 * Assert that all required callbacks are present. That makes it a bit
41 * easier to keep AMs up to date, e.g. when forward porting them to a new
42 * major version.
43 */
44 Assert(routine->scan_begin != NULL);
45 Assert(routine->scan_end != NULL);
46 Assert(routine->scan_rescan != NULL);
47 Assert(routine->scan_getnextslot != NULL);
48
52
53 Assert(routine->index_fetch_begin != NULL);
54 Assert(routine->index_fetch_reset != NULL);
55 Assert(routine->index_fetch_end != NULL);
56 Assert(routine->index_fetch_tuple != NULL);
57
59 Assert(routine->tuple_tid_valid != NULL);
60 Assert(routine->tuple_get_latest_tid != NULL);
62 Assert(routine->index_delete_tuples != NULL);
63
64 Assert(routine->tuple_insert != NULL);
65
66 /*
67 * Could be made optional, but would require throwing error during
68 * parse-analysis.
69 */
72
73 Assert(routine->multi_insert != NULL);
74 Assert(routine->tuple_delete != NULL);
75 Assert(routine->tuple_update != NULL);
76 Assert(routine->tuple_lock != NULL);
77
80 Assert(routine->relation_copy_data != NULL);
82 Assert(routine->relation_vacuum != NULL);
86 Assert(routine->index_validate_scan != NULL);
87
88 Assert(routine->relation_size != NULL);
90
92
95
96 return routine;
97}
#define OidFunctionCall0(functionId)
Definition fmgr.h:720
#define IsA(nodeptr, _type_)
Definition nodes.h:164
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332

References Assert, DatumGetPointer(), elog, ERROR, fb(), TableAmRoutine::index_build_range_scan, TableAmRoutine::index_delete_tuples, TableAmRoutine::index_fetch_begin, TableAmRoutine::index_fetch_end, TableAmRoutine::index_fetch_reset, TableAmRoutine::index_fetch_tuple, TableAmRoutine::index_validate_scan, IsA, TableAmRoutine::multi_insert, OidFunctionCall0, TableAmRoutine::parallelscan_estimate, TableAmRoutine::parallelscan_initialize, TableAmRoutine::parallelscan_reinitialize, TableAmRoutine::relation_copy_data, TableAmRoutine::relation_copy_for_cluster, TableAmRoutine::relation_estimate_size, TableAmRoutine::relation_needs_toast_table, TableAmRoutine::relation_nontransactional_truncate, TableAmRoutine::relation_set_new_filelocator, TableAmRoutine::relation_size, TableAmRoutine::relation_vacuum, TableAmRoutine::scan_analyze_next_block, TableAmRoutine::scan_analyze_next_tuple, TableAmRoutine::scan_begin, TableAmRoutine::scan_end, TableAmRoutine::scan_getnextslot, TableAmRoutine::scan_rescan, TableAmRoutine::scan_sample_next_block, TableAmRoutine::scan_sample_next_tuple, TableAmRoutine::tuple_complete_speculative, TableAmRoutine::tuple_delete, TableAmRoutine::tuple_fetch_row_version, TableAmRoutine::tuple_get_latest_tid, TableAmRoutine::tuple_insert, TableAmRoutine::tuple_insert_speculative, TableAmRoutine::tuple_lock, TableAmRoutine::tuple_satisfies_snapshot, TableAmRoutine::tuple_tid_valid, and TableAmRoutine::tuple_update.

Referenced by InitTableAmRoutine().

◆ simple_table_tuple_delete()

void simple_table_tuple_delete ( Relation  rel,
ItemPointer  tid,
Snapshot  snapshot 
)
extern

Definition at line 316 of file tableam.c.

317{
319 TM_FailureData tmfd;
320
321 result = table_tuple_delete(rel, tid,
323 0, snapshot, InvalidSnapshot,
324 true /* wait for commit */ ,
325 &tmfd);
326
327 switch (result)
328 {
329 case TM_SelfModified:
330 /* Tuple was already updated in current command? */
331 elog(ERROR, "tuple already updated by self");
332 break;
333
334 case TM_Ok:
335 /* done successfully */
336 break;
337
338 case TM_Updated:
339 elog(ERROR, "tuple concurrently updated");
340 break;
341
342 case TM_Deleted:
343 elog(ERROR, "tuple concurrently deleted");
344 break;
345
346 default:
347 elog(ERROR, "unrecognized table_tuple_delete status: %u", result);
348 break;
349 }
350}
#define InvalidSnapshot
Definition snapshot.h:119
CommandId GetCurrentCommandId(bool used)
Definition xact.c:831

References elog, ERROR, GetCurrentCommandId(), InvalidSnapshot, result, table_tuple_delete(), TM_Deleted, TM_Ok, TM_SelfModified, and TM_Updated.

Referenced by ExecSimpleRelationDelete().

◆ simple_table_tuple_insert()

void simple_table_tuple_insert ( Relation  rel,
TupleTableSlot slot 
)
extern

Definition at line 302 of file tableam.c.

303{
304 table_tuple_insert(rel, slot, GetCurrentCommandId(true), 0, NULL);
305}

References fb(), GetCurrentCommandId(), and table_tuple_insert().

Referenced by ExecSimpleRelationInsert().

◆ simple_table_tuple_update()

void simple_table_tuple_update ( Relation  rel,
ItemPointer  otid,
TupleTableSlot slot,
Snapshot  snapshot,
TU_UpdateIndexes update_indexes 
)
extern

Definition at line 361 of file tableam.c.

365{
367 TM_FailureData tmfd;
368 LockTupleMode lockmode;
369
370 result = table_tuple_update(rel, otid, slot,
372 0, snapshot, InvalidSnapshot,
373 true /* wait for commit */ ,
374 &tmfd, &lockmode, update_indexes);
375
376 switch (result)
377 {
378 case TM_SelfModified:
379 /* Tuple was already updated in current command? */
380 elog(ERROR, "tuple already updated by self");
381 break;
382
383 case TM_Ok:
384 /* done successfully */
385 break;
386
387 case TM_Updated:
388 elog(ERROR, "tuple concurrently updated");
389 break;
390
391 case TM_Deleted:
392 elog(ERROR, "tuple concurrently deleted");
393 break;
394
395 default:
396 elog(ERROR, "unrecognized table_tuple_update status: %u", result);
397 break;
398 }
399}

References elog, ERROR, fb(), GetCurrentCommandId(), InvalidSnapshot, result, table_tuple_update(), TM_Deleted, TM_Ok, TM_SelfModified, and TM_Updated.

Referenced by ExecSimpleRelationUpdate().

◆ table_beginscan()

◆ table_beginscan_analyze()

static TableScanDesc table_beginscan_analyze ( Relation  rel)
inlinestatic

Definition at line 1049 of file tableam.h.

1050{
1051 uint32 flags = SO_TYPE_ANALYZE;
1052
1053 return table_beginscan_common(rel, NULL, 0, NULL, NULL,
1054 flags, SO_NONE);
1055}

References fb(), IndexFetchTableData::flags, IndexFetchTableData::rel, SO_NONE, SO_TYPE_ANALYZE, and table_beginscan_common().

Referenced by acquire_sample_rows().

◆ table_beginscan_bm()

static TableScanDesc table_beginscan_bm ( Relation  rel,
Snapshot  snapshot,
int  nkeys,
ScanKeyData key,
uint32  flags 
)
inlinestatic

◆ table_beginscan_catalog()

TableScanDesc table_beginscan_catalog ( Relation  relation,
int  nkeys,
ScanKeyData key 
)
extern

◆ table_beginscan_common()

static TableScanDesc table_beginscan_common ( Relation  rel,
Snapshot  snapshot,
int  nkeys,
ScanKeyData key,
ParallelTableScanDesc  pscan,
uint32  flags,
uint32  user_flags 
)
static

Definition at line 917 of file tableam.h.

920{
922 Assert((flags & ~SO_INTERNAL_FLAGS) == 0);
923 flags |= user_flags;
924
925 /*
926 * We don't allow scans to be started while CheckXidAlive is set, except
927 * via systable_beginscan() et al. See detailed comments in xact.c where
928 * these variables are declared.
929 */
931 elog(ERROR, "scan started during logical decoding");
932
933 return rel->rd_tableam->scan_begin(rel, snapshot, nkeys, key, pscan, flags);
934}

References Assert, bsysscan, CheckXidAlive, elog, ERROR, fb(), IndexFetchTableData::flags, RelationData::rd_tableam, IndexFetchTableData::rel, TableAmRoutine::scan_begin, SO_INTERNAL_FLAGS, TransactionIdIsValid, and unlikely.

Referenced by table_beginscan(), table_beginscan_analyze(), table_beginscan_bm(), table_beginscan_catalog(), table_beginscan_parallel(), table_beginscan_parallel_tidrange(), table_beginscan_sampling(), table_beginscan_strat(), table_beginscan_tid(), and table_beginscan_tidrange().

◆ table_beginscan_parallel()

TableScanDesc table_beginscan_parallel ( Relation  relation,
ParallelTableScanDesc  pscan,
uint32  flags 
)
extern

Definition at line 166 of file tableam.c.

168{
169 Snapshot snapshot;
172
173 Assert(RelFileLocatorEquals(relation->rd_locator, pscan->phs_locator));
174
175 if (!pscan->phs_snapshot_any)
176 {
177 /* Snapshot was serialized -- restore it */
178 snapshot = RestoreSnapshot((char *) pscan + pscan->phs_snapshot_off);
179 RegisterSnapshot(snapshot);
181 }
182 else
183 {
184 /* SnapshotAny passed by caller (not serialized) */
185 snapshot = SnapshotAny;
186 }
187
188 return table_beginscan_common(relation, snapshot, 0, NULL,
189 pscan, internal_flags, flags);
190}
#define RelFileLocatorEquals(locator1, locator2)
Snapshot RestoreSnapshot(char *start_address)
Definition snapmgr.c:1793
#define SnapshotAny
Definition snapmgr.h:33
RelFileLocator rd_locator
Definition rel.h:57

References Assert, fb(), RelationData::rd_locator, RegisterSnapshot(), RelFileLocatorEquals, RestoreSnapshot(), SnapshotAny, SO_ALLOW_PAGEMODE, SO_ALLOW_STRAT, SO_ALLOW_SYNC, SO_TEMP_SNAPSHOT, SO_TYPE_SEQSCAN, and table_beginscan_common().

Referenced by _brin_parallel_scan_and_build(), _bt_parallel_scan_and_sort(), _gin_parallel_scan_and_build(), ExecSeqScanInitializeDSM(), and ExecSeqScanInitializeWorker().

◆ table_beginscan_parallel_tidrange()

TableScanDesc table_beginscan_parallel_tidrange ( Relation  relation,
ParallelTableScanDesc  pscan,
uint32  flags 
)
extern

Definition at line 193 of file tableam.c.

196{
197 Snapshot snapshot;
200
201 Assert(RelFileLocatorEquals(relation->rd_locator, pscan->phs_locator));
202
203 /* disable syncscan in parallel tid range scan. */
204 pscan->phs_syncscan = false;
205
206 if (!pscan->phs_snapshot_any)
207 {
208 /* Snapshot was serialized -- restore it */
209 snapshot = RestoreSnapshot((char *) pscan + pscan->phs_snapshot_off);
210 RegisterSnapshot(snapshot);
212 }
213 else
214 {
215 /* SnapshotAny passed by caller (not serialized) */
216 snapshot = SnapshotAny;
217 }
218
219 sscan = table_beginscan_common(relation, snapshot, 0, NULL,
220 pscan, internal_flags, flags);
221 return sscan;
222}

References Assert, fb(), RelationData::rd_locator, RegisterSnapshot(), RelFileLocatorEquals, RestoreSnapshot(), SnapshotAny, SO_ALLOW_PAGEMODE, SO_TEMP_SNAPSHOT, SO_TYPE_TIDRANGESCAN, and table_beginscan_common().

Referenced by ExecTidRangeScanInitializeDSM(), and ExecTidRangeScanInitializeWorker().

◆ table_beginscan_sampling()

static TableScanDesc table_beginscan_sampling ( Relation  rel,
Snapshot  snapshot,
int  nkeys,
ScanKeyData key,
bool  allow_strat,
bool  allow_sync,
bool  allow_pagemode,
uint32  flags 
)
inlinestatic

◆ table_beginscan_strat()

static TableScanDesc table_beginscan_strat ( Relation  rel,
Snapshot  snapshot,
int  nkeys,
ScanKeyData key,
bool  allow_strat,
bool  allow_sync 
)
inlinestatic

◆ table_beginscan_tid()

static TableScanDesc table_beginscan_tid ( Relation  rel,
Snapshot  snapshot 
)
inlinestatic

Definition at line 1035 of file tableam.h.

1036{
1037 uint32 flags = SO_TYPE_TIDSCAN;
1038
1039 return table_beginscan_common(rel, snapshot, 0, NULL, NULL,
1040 flags, SO_NONE);
1041}

References fb(), IndexFetchTableData::flags, IndexFetchTableData::rel, SO_NONE, SO_TYPE_TIDSCAN, and table_beginscan_common().

Referenced by currtid_internal(), and TidListEval().

◆ table_beginscan_tidrange()

static TableScanDesc table_beginscan_tidrange ( Relation  rel,
Snapshot  snapshot,
ItemPointer  mintid,
ItemPointer  maxtid,
uint32  flags 
)
inlinestatic

Definition at line 1119 of file tableam.h.

1122{
1125
1126 sscan = table_beginscan_common(rel, snapshot, 0, NULL, NULL,
1127 internal_flags, flags);
1128
1129 /* Set the range of TIDs to scan */
1130 sscan->rs_rd->rd_tableam->scan_set_tidrange(sscan, mintid, maxtid);
1131
1132 return sscan;
1133}

References fb(), IndexFetchTableData::flags, IndexFetchTableData::rel, SO_ALLOW_PAGEMODE, SO_TYPE_TIDRANGESCAN, and table_beginscan_common().

Referenced by TidRangeNext().

◆ table_block_parallelscan_estimate()

Size table_block_parallelscan_estimate ( Relation  rel)
extern

Definition at line 408 of file tableam.c.

409{
410 return sizeof(ParallelBlockTableScanDescData);
411}

◆ table_block_parallelscan_initialize()

Size table_block_parallelscan_initialize ( Relation  rel,
ParallelTableScanDesc  pscan 
)
extern

Definition at line 414 of file tableam.c.

415{
417
419 bpscan->phs_nblocks = RelationGetNumberOfBlocks(rel);
420 /* compare phs_syncscan initialization to similar logic in initscan */
421 bpscan->base.phs_syncscan = synchronize_seqscans &&
423 bpscan->phs_nblocks > NBuffers / 4;
424 SpinLockInit(&bpscan->phs_mutex);
425 bpscan->phs_startblock = InvalidBlockNumber;
426 bpscan->phs_numblock = InvalidBlockNumber;
427 pg_atomic_init_u64(&bpscan->phs_nallocated, 0);
428
429 return sizeof(ParallelBlockTableScanDescData);
430}
static void pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition atomics.h:453
#define RelationGetNumberOfBlocks(reln)
Definition bufmgr.h:309
int NBuffers
Definition globals.c:144
#define RelationUsesLocalBuffers(relation)
Definition rel.h:648
struct ParallelBlockTableScanDescData * ParallelBlockTableScanDesc
Definition relscan.h:109
static void SpinLockInit(volatile slock_t *lock)
Definition spin.h:50
ParallelTableScanDescData base
Definition relscan.h:99
RelFileLocator phs_locator
Definition relscan.h:87
bool synchronize_seqscans
Definition tableam.c:50

References ParallelBlockTableScanDescData::base, fb(), InvalidBlockNumber, NBuffers, pg_atomic_init_u64(), ParallelTableScanDescData::phs_locator, RelationData::rd_locator, RelationGetNumberOfBlocks, RelationUsesLocalBuffers, SpinLockInit(), and synchronize_seqscans.

◆ table_block_parallelscan_nextpage()

BlockNumber table_block_parallelscan_nextpage ( Relation  rel,
ParallelBlockTableScanWorker  pbscanwork,
ParallelBlockTableScanDesc  pbscan 
)
extern

Definition at line 548 of file tableam.c.

551{
553 BlockNumber page;
554 uint64 nallocated;
555
556 /*
557 * The logic below allocates block numbers out to parallel workers in a
558 * way that each worker will receive a set of consecutive block numbers to
559 * scan. Earlier versions of this would allocate the next highest block
560 * number to the next worker to call this function. This would generally
561 * result in workers never receiving consecutive block numbers. Some
562 * operating systems would not detect the sequential I/O pattern due to
563 * each backend being a different process which could result in poor
564 * performance due to inefficient or no readahead. To work around this
565 * issue, we now allocate a range of block numbers for each worker and
566 * when they come back for another block, we give them the next one in
567 * that range until the range is complete. When the worker completes the
568 * range of blocks we then allocate another range for it and return the
569 * first block number from that range.
570 *
571 * Here we name these ranges of blocks "chunks". The initial size of
572 * these chunks is determined in table_block_parallelscan_startblock_init
573 * based on the number of blocks to scan. Towards the end of the scan, we
574 * start making reductions in the size of the chunks in order to attempt
575 * to divide the remaining work over all the workers as evenly as
576 * possible.
577 *
578 * Here pbscanwork is local worker memory. phsw_chunk_remaining tracks
579 * the number of blocks remaining in the chunk. When that reaches 0 then
580 * we must allocate a new chunk for the worker.
581 *
582 * phs_nallocated tracks how many blocks have been allocated to workers
583 * already. When phs_nallocated >= rs_nblocks, all blocks have been
584 * allocated.
585 *
586 * Because we use an atomic fetch-and-add to fetch the current value, the
587 * phs_nallocated counter will exceed rs_nblocks, because workers will
588 * still increment the value, when they try to allocate the next block but
589 * all blocks have been allocated already. The counter must be 64 bits
590 * wide because of that, to avoid wrapping around when scan_nblocks is
591 * close to 2^32.
592 *
593 * The actual block to return is calculated by adding the counter to the
594 * starting block number, modulo phs_nblocks.
595 */
596
597 /* First, figure out how many blocks we're planning on scanning */
598 if (pbscan->phs_numblock == InvalidBlockNumber)
599 scan_nblocks = pbscan->phs_nblocks;
600 else
601 scan_nblocks = pbscan->phs_numblock;
602
603 /*
604 * Now check if we have any remaining blocks in a previous chunk for this
605 * worker. We must consume all of the blocks from that before we allocate
606 * a new chunk to the worker.
607 */
608 if (pbscanwork->phsw_chunk_remaining > 0)
609 {
610 /*
611 * Give them the next block in the range and update the remaining
612 * number of blocks.
613 */
614 nallocated = ++pbscanwork->phsw_nallocated;
615 pbscanwork->phsw_chunk_remaining--;
616 }
617 else
618 {
619 /*
620 * When we've only got PARALLEL_SEQSCAN_RAMPDOWN_CHUNKS chunks
621 * remaining in the scan, we half the chunk size. Since we reduce the
622 * chunk size here, we'll hit this again after doing
623 * PARALLEL_SEQSCAN_RAMPDOWN_CHUNKS at the new size. After a few
624 * iterations of this, we'll end up doing the last few blocks with the
625 * chunk size set to 1.
626 */
627 if (pbscanwork->phsw_chunk_size > 1 &&
628 pbscanwork->phsw_nallocated > scan_nblocks -
629 (pbscanwork->phsw_chunk_size * PARALLEL_SEQSCAN_RAMPDOWN_CHUNKS))
630 pbscanwork->phsw_chunk_size >>= 1;
631
632 nallocated = pbscanwork->phsw_nallocated =
633 pg_atomic_fetch_add_u64(&pbscan->phs_nallocated,
634 pbscanwork->phsw_chunk_size);
635
636 /*
637 * Set the remaining number of blocks in this chunk so that subsequent
638 * calls from this worker continue on with this chunk until it's done.
639 */
640 pbscanwork->phsw_chunk_remaining = pbscanwork->phsw_chunk_size - 1;
641 }
642
643 /* Check if we've run out of blocks to scan */
644 if (nallocated >= scan_nblocks)
645 page = InvalidBlockNumber; /* all blocks have been allocated */
646 else
647 page = (nallocated + pbscan->phs_startblock) % pbscan->phs_nblocks;
648
649 /*
650 * Report scan location. Normally, we report the current page number.
651 * When we reach the end of the scan, though, we report the starting page,
652 * not the ending page, just so the starting positions for later scans
653 * doesn't slew backwards. We only report the position at the end of the
654 * scan once, though: subsequent callers will report nothing.
655 */
656 if (pbscan->base.phs_syncscan)
657 {
658 if (page != InvalidBlockNumber)
659 ss_report_location(rel, page);
660 else if (nallocated == pbscan->phs_nblocks)
661 ss_report_location(rel, pbscan->phs_startblock);
662 }
663
664 return page;
665}
static uint64 pg_atomic_fetch_add_u64(volatile pg_atomic_uint64 *ptr, int64 add_)
Definition atomics.h:532
void ss_report_location(Relation rel, BlockNumber location)
Definition syncscan.c:287
#define PARALLEL_SEQSCAN_RAMPDOWN_CHUNKS
Definition tableam.c:44

References fb(), InvalidBlockNumber, PARALLEL_SEQSCAN_RAMPDOWN_CHUNKS, pg_atomic_fetch_add_u64(), and ss_report_location().

Referenced by heap_scan_stream_read_next_parallel().

◆ table_block_parallelscan_reinitialize()

void table_block_parallelscan_reinitialize ( Relation  rel,
ParallelTableScanDesc  pscan 
)
extern

Definition at line 433 of file tableam.c.

434{
436
437 pg_atomic_write_u64(&bpscan->phs_nallocated, 0);
438}
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition atomics.h:485

References fb(), and pg_atomic_write_u64().

◆ table_block_parallelscan_startblock_init()

void table_block_parallelscan_startblock_init ( Relation  rel,
ParallelBlockTableScanWorker  pbscanwork,
ParallelBlockTableScanDesc  pbscan,
BlockNumber  startblock,
BlockNumber  numblocks 
)
extern

Definition at line 453 of file tableam.c.

458{
459 StaticAssertDecl(MaxBlockNumber <= 0xFFFFFFFE,
460 "pg_nextpower2_32 may be too small for non-standard BlockNumber width");
461
464
465 /* Reset the state we use for controlling allocation size. */
466 memset(pbscanwork, 0, sizeof(*pbscanwork));
467
468retry:
469 /* Grab the spinlock. */
470 SpinLockAcquire(&pbscan->phs_mutex);
471
472 /*
473 * When the caller specified a limit on the number of blocks to scan, set
474 * that in the ParallelBlockTableScanDesc, if it's not been done by
475 * another worker already.
476 */
478 pbscan->phs_numblock == InvalidBlockNumber)
479 {
480 pbscan->phs_numblock = numblocks;
481 }
482
483 /*
484 * If the scan's phs_startblock has not yet been initialized, we must do
485 * so now. If a startblock was specified, start there, otherwise if this
486 * is not a synchronized scan, we just start at block 0, but if it is a
487 * synchronized scan, we must get the starting position from the
488 * synchronized scan machinery. We can't hold the spinlock while doing
489 * that, though, so release the spinlock, get the information we need, and
490 * retry. If nobody else has initialized the scan in the meantime, we'll
491 * fill in the value we fetched on the second time through.
492 */
493 if (pbscan->phs_startblock == InvalidBlockNumber)
494 {
495 if (startblock != InvalidBlockNumber)
496 pbscan->phs_startblock = startblock;
497 else if (!pbscan->base.phs_syncscan)
498 pbscan->phs_startblock = 0;
500 pbscan->phs_startblock = sync_startpage;
501 else
502 {
503 SpinLockRelease(&pbscan->phs_mutex);
504 sync_startpage = ss_get_location(rel, pbscan->phs_nblocks);
505 goto retry;
506 }
507 }
508 SpinLockRelease(&pbscan->phs_mutex);
509
510 /*
511 * Figure out how many blocks we're going to scan; either all of them, or
512 * just phs_numblock's worth, if a limit has been imposed.
513 */
514 if (pbscan->phs_numblock == InvalidBlockNumber)
515 scan_nblocks = pbscan->phs_nblocks;
516 else
517 scan_nblocks = pbscan->phs_numblock;
518
519 /*
520 * We determine the chunk size based on scan_nblocks. First we split
521 * scan_nblocks into PARALLEL_SEQSCAN_NCHUNKS chunks then we calculate the
522 * next highest power of 2 number of the result. This means we split the
523 * blocks we're scanning into somewhere between PARALLEL_SEQSCAN_NCHUNKS
524 * and PARALLEL_SEQSCAN_NCHUNKS / 2 chunks.
525 */
526 pbscanwork->phsw_chunk_size = pg_nextpower2_32(Max(scan_nblocks /
528
529 /*
530 * Ensure we don't go over the maximum chunk size with larger tables. This
531 * means we may get much more than PARALLEL_SEQSCAN_NCHUNKS for larger
532 * tables. Too large a chunk size has been shown to be detrimental to
533 * sequential scan performance.
534 */
535 pbscanwork->phsw_chunk_size = Min(pbscanwork->phsw_chunk_size,
537}
#define MaxBlockNumber
Definition block.h:35
#define Min(x, y)
Definition c.h:1091
#define Max(x, y)
Definition c.h:1085
#define StaticAssertDecl(condition, errmessage)
Definition c.h:1008
static uint32 pg_nextpower2_32(uint32 num)
static void SpinLockRelease(volatile slock_t *lock)
Definition spin.h:62
static void SpinLockAcquire(volatile slock_t *lock)
Definition spin.h:56
BlockNumber ss_get_location(Relation rel, BlockNumber relnblocks)
Definition syncscan.c:252
#define PARALLEL_SEQSCAN_MAX_CHUNK_SIZE
Definition tableam.c:46
#define PARALLEL_SEQSCAN_NCHUNKS
Definition tableam.c:42

References fb(), InvalidBlockNumber, Max, MaxBlockNumber, Min, PARALLEL_SEQSCAN_MAX_CHUNK_SIZE, PARALLEL_SEQSCAN_NCHUNKS, pg_nextpower2_32(), SpinLockAcquire(), SpinLockRelease(), ss_get_location(), and StaticAssertDecl.

Referenced by heap_scan_stream_read_next_parallel().

◆ table_block_relation_estimate_size()

void table_block_relation_estimate_size ( Relation  rel,
int32 attr_widths,
BlockNumber pages,
double tuples,
double allvisfrac,
Size  overhead_bytes_per_tuple,
Size  usable_bytes_per_page 
)
extern

Definition at line 718 of file tableam.c.

723{
725 BlockNumber relpages;
726 double reltuples;
727 BlockNumber relallvisible;
728 double density;
729
730 /* it should have storage, so we can call the smgr */
732
733 /* coerce values in pg_class to more desirable types */
734 relpages = (BlockNumber) rel->rd_rel->relpages;
735 reltuples = (double) rel->rd_rel->reltuples;
736 relallvisible = (BlockNumber) rel->rd_rel->relallvisible;
737
738 /*
739 * HACK: if the relation has never yet been vacuumed, use a minimum size
740 * estimate of 10 pages. The idea here is to avoid assuming a
741 * newly-created table is really small, even if it currently is, because
742 * that may not be true once some data gets loaded into it. Once a vacuum
743 * or analyze cycle has been done on it, it's more reasonable to believe
744 * the size is somewhat stable.
745 *
746 * (Note that this is only an issue if the plan gets cached and used again
747 * after the table has been filled. What we're trying to avoid is using a
748 * nestloop-type plan on a table that has grown substantially since the
749 * plan was made. Normally, autovacuum/autoanalyze will occur once enough
750 * inserts have happened and cause cached-plan invalidation; but that
751 * doesn't happen instantaneously, and it won't happen at all for cases
752 * such as temporary tables.)
753 *
754 * We test "never vacuumed" by seeing whether reltuples < 0.
755 *
756 * If the table has inheritance children, we don't apply this heuristic.
757 * Totally empty parent tables are quite common, so we should be willing
758 * to believe that they are empty.
759 */
760 if (curpages < 10 &&
761 reltuples < 0 &&
762 !rel->rd_rel->relhassubclass)
763 curpages = 10;
764
765 /* report estimated # pages */
766 *pages = curpages;
767 /* quick exit if rel is clearly empty */
768 if (curpages == 0)
769 {
770 *tuples = 0;
771 *allvisfrac = 0;
772 return;
773 }
774
775 /* estimate number of tuples from previous tuple density */
776 if (reltuples >= 0 && relpages > 0)
777 density = reltuples / (double) relpages;
778 else
779 {
780 /*
781 * When we have no data because the relation was never yet vacuumed,
782 * estimate tuple width from attribute datatypes. We assume here that
783 * the pages are completely full, which is OK for tables but is
784 * probably an overestimate for indexes. Fortunately
785 * get_relation_info() can clamp the overestimate to the parent
786 * table's size.
787 *
788 * Note: this code intentionally disregards alignment considerations,
789 * because (a) that would be gilding the lily considering how crude
790 * the estimate is, (b) it creates platform dependencies in the
791 * default plans which are kind of a headache for regression testing,
792 * and (c) different table AMs might use different padding schemes.
793 */
795 int fillfactor;
796
797 /*
798 * Without reltuples/relpages, we also need to consider fillfactor.
799 * The other branch considers it implicitly by calculating density
800 * from actual relpages/reltuples statistics.
801 */
803
806 /* note: integer division is intentional here */
808 /* There's at least one row on the page, even with low fillfactor. */
810 }
811 *tuples = rint(density * (double) curpages);
812
813 /*
814 * We use relallvisible as-is, rather than scaling it up like we do for
815 * the pages and tuples counts, on the theory that any pages added since
816 * the last VACUUM are most likely not marked all-visible. But costsize.c
817 * wants it converted to a fraction.
818 */
819 if (relallvisible == 0 || curpages <= 0)
820 *allvisfrac = 0;
821 else if ((double) relallvisible >= curpages)
822 *allvisfrac = 1;
823 else
824 *allvisfrac = (double) relallvisible / curpages;
825}
double clamp_row_est(double nrows)
Definition costsize.c:214
static int fillfactor
Definition pgbench.c:188
int32 get_rel_data_width(Relation rel, int32 *attr_widths)
Definition plancat.c:1430
#define RelationGetFillFactor(relation, defaultff)
Definition rel.h:376
#define HEAP_DEFAULT_FILLFACTOR
Definition rel.h:362
Form_pg_class rd_rel
Definition rel.h:111

References clamp_row_est(), fb(), fillfactor, get_rel_data_width(), HEAP_DEFAULT_FILLFACTOR, RelationData::rd_rel, RelationGetFillFactor, and RelationGetNumberOfBlocks.

Referenced by heapam_estimate_rel_size().

◆ table_block_relation_size()

uint64 table_block_relation_size ( Relation  rel,
ForkNumber  forkNumber 
)
extern

Definition at line 681 of file tableam.c.

682{
683 uint64 nblocks = 0;
684
685 /* InvalidForkNumber indicates returning the size for all forks */
687 {
688 for (int i = 0; i < MAX_FORKNUM; i++)
689 nblocks += smgrnblocks(RelationGetSmgr(rel), i);
690 }
691 else
692 nblocks = smgrnblocks(RelationGetSmgr(rel), forkNumber);
693
694 return nblocks * BLCKSZ;
695}
int i
Definition isn.c:77
static SMgrRelation RelationGetSmgr(Relation rel)
Definition rel.h:578
@ InvalidForkNumber
Definition relpath.h:57
#define MAX_FORKNUM
Definition relpath.h:70
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
Definition smgr.c:819

References fb(), i, InvalidForkNumber, MAX_FORKNUM, RelationGetSmgr(), and smgrnblocks().

◆ table_endscan()

static void table_endscan ( TableScanDesc  scan)
inlinestatic

◆ table_finish_bulk_insert()

static void table_finish_bulk_insert ( Relation  rel,
uint32  options 
)
inlinestatic

◆ table_index_build_range_scan()

static double table_index_build_range_scan ( Relation  table_rel,
Relation  index_rel,
IndexInfo index_info,
bool  allow_sync,
bool  anyvisible,
bool  progress,
BlockNumber  start_blockno,
BlockNumber  numblocks,
IndexBuildCallback  callback,
void callback_state,
TableScanDesc  scan 
)
inlinestatic

Definition at line 1880 of file tableam.h.

1891{
1892 return table_rel->rd_tableam->index_build_range_scan(table_rel,
1893 index_rel,
1894 index_info,
1895 allow_sync,
1896 anyvisible,
1897 progress,
1899 numblocks,
1900 callback,
1901 callback_state,
1902 scan);
1903}

References callback(), fb(), and progress.

Referenced by summarize_range().

◆ table_index_build_scan()

static double table_index_build_scan ( Relation  table_rel,
Relation  index_rel,
IndexInfo index_info,
bool  allow_sync,
bool  progress,
IndexBuildCallback  callback,
void callback_state,
TableScanDesc  scan 
)
inlinestatic

Definition at line 1847 of file tableam.h.

1855{
1856 return table_rel->rd_tableam->index_build_range_scan(table_rel,
1857 index_rel,
1858 index_info,
1859 allow_sync,
1860 false,
1861 progress,
1862 0,
1864 callback,
1865 callback_state,
1866 scan);
1867}

References callback(), fb(), InvalidBlockNumber, and progress.

Referenced by _brin_parallel_scan_and_build(), _bt_parallel_scan_and_sort(), _bt_spools_heapscan(), _gin_parallel_scan_and_build(), blbuild(), brinbuild(), bt_check_every_level(), ginbuild(), gistbuild(), hashbuild(), and spgbuild().

◆ table_index_delete_tuples()

static TransactionId table_index_delete_tuples ( Relation  rel,
TM_IndexDeleteOp delstate 
)
inlinestatic

◆ table_index_fetch_begin()

static IndexFetchTableData * table_index_fetch_begin ( Relation  rel,
uint32  flags 
)
inlinestatic

Definition at line 1246 of file tableam.h.

1247{
1248 Assert((flags & SO_INTERNAL_FLAGS) == 0);
1249
1250 /*
1251 * We don't allow scans to be started while CheckXidAlive is set, except
1252 * via systable_beginscan() et al. See detailed comments in xact.c where
1253 * these variables are declared.
1254 */
1256 elog(ERROR, "scan started during logical decoding");
1257
1258 return rel->rd_tableam->index_fetch_begin(rel, flags);
1259}

References Assert, bsysscan, CheckXidAlive, elog, ERROR, IndexFetchTableData::flags, TableAmRoutine::index_fetch_begin, RelationData::rd_tableam, IndexFetchTableData::rel, SO_INTERNAL_FLAGS, TransactionIdIsValid, and unlikely.

Referenced by index_beginscan(), index_beginscan_parallel(), table_index_fetch_tuple_check(), and unique_key_recheck().

◆ table_index_fetch_end()

static void table_index_fetch_end ( struct IndexFetchTableData scan)
inlinestatic

◆ table_index_fetch_reset()

static void table_index_fetch_reset ( struct IndexFetchTableData scan)
inlinestatic

◆ table_index_fetch_tuple()

static bool table_index_fetch_tuple ( struct IndexFetchTableData scan,
ItemPointer  tid,
Snapshot  snapshot,
TupleTableSlot slot,
bool call_again,
bool all_dead 
)
inlinestatic

Definition at line 1305 of file tableam.h.

1310{
1311 return scan->rel->rd_tableam->index_fetch_tuple(scan, tid, snapshot,
1312 slot, call_again,
1313 all_dead);
1314}

References fb(), TableAmRoutine::index_fetch_tuple, RelationData::rd_tableam, and IndexFetchTableData::rel.

Referenced by index_fetch_heap(), table_index_fetch_tuple_check(), and unique_key_recheck().

◆ table_index_fetch_tuple_check()

bool table_index_fetch_tuple_check ( Relation  rel,
ItemPointer  tid,
Snapshot  snapshot,
bool all_dead 
)
extern

Definition at line 242 of file tableam.c.

246{
248 TupleTableSlot *slot;
249 bool call_again = false;
250 bool found;
251
252 slot = table_slot_create(rel, NULL);
253 scan = table_index_fetch_begin(rel, SO_NONE);
254 found = table_index_fetch_tuple(scan, tid, snapshot, slot, &call_again,
255 all_dead);
258
259 return found;
260}
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition tableam.c:92

References ExecDropSingleTupleTableSlot(), fb(), SO_NONE, table_index_fetch_begin(), table_index_fetch_end(), table_index_fetch_tuple(), and table_slot_create().

Referenced by _bt_check_unique().

◆ table_index_validate_scan()

static void table_index_validate_scan ( Relation  table_rel,
Relation  index_rel,
IndexInfo index_info,
Snapshot  snapshot,
ValidateIndexState state 
)
inlinestatic

Definition at line 1911 of file tableam.h.

1916{
1917 table_rel->rd_tableam->index_validate_scan(table_rel,
1918 index_rel,
1919 index_info,
1920 snapshot,
1921 state);
1922}

References fb().

Referenced by validate_index().

◆ table_multi_insert()

static void table_multi_insert ( Relation  rel,
TupleTableSlot **  slots,
int  nslots,
CommandId  cid,
uint32  options,
BulkInsertStateData bistate 
)
inlinestatic

Definition at line 1513 of file tableam.h.

1515{
1516 rel->rd_tableam->multi_insert(rel, slots, nslots,
1517 cid, options, bistate);
1518}

References fb(), TableAmRoutine::multi_insert, RelationData::rd_tableam, and IndexFetchTableData::rel.

Referenced by CopyMultiInsertBufferFlush().

◆ table_parallelscan_estimate()

Size table_parallelscan_estimate ( Relation  rel,
Snapshot  snapshot 
)
extern

Definition at line 131 of file tableam.c.

132{
133 Size sz = 0;
134
135 if (IsMVCCSnapshot(snapshot))
136 sz = add_size(sz, EstimateSnapshotSpace(snapshot));
137 else
138 Assert(snapshot == SnapshotAny);
139
141
142 return sz;
143}
Size add_size(Size s1, Size s2)
Definition shmem.c:1048
Size EstimateSnapshotSpace(Snapshot snapshot)
Definition snapmgr.c:1712
#define IsMVCCSnapshot(snapshot)
Definition snapmgr.h:59

References add_size(), Assert, EstimateSnapshotSpace(), fb(), IsMVCCSnapshot, TableAmRoutine::parallelscan_estimate, RelationData::rd_tableam, and SnapshotAny.

Referenced by _brin_parallel_estimate_shared(), _bt_parallel_estimate_shared(), _gin_parallel_estimate_shared(), ExecSeqScanEstimate(), and ExecTidRangeScanEstimate().

◆ table_parallelscan_initialize()

void table_parallelscan_initialize ( Relation  rel,
ParallelTableScanDesc  pscan,
Snapshot  snapshot 
)
extern

Definition at line 146 of file tableam.c.

148{
150
151 pscan->phs_snapshot_off = snapshot_off;
152
153 if (IsMVCCSnapshot(snapshot))
154 {
155 SerializeSnapshot(snapshot, (char *) pscan + pscan->phs_snapshot_off);
156 pscan->phs_snapshot_any = false;
157 }
158 else
159 {
160 Assert(snapshot == SnapshotAny);
161 pscan->phs_snapshot_any = true;
162 }
163}
void SerializeSnapshot(Snapshot snapshot, char *start_address)
Definition snapmgr.c:1736

References Assert, fb(), IsMVCCSnapshot, TableAmRoutine::parallelscan_initialize, RelationData::rd_tableam, SerializeSnapshot(), and SnapshotAny.

Referenced by _brin_begin_parallel(), _bt_begin_parallel(), _gin_begin_parallel(), ExecSeqScanInitializeDSM(), and ExecTidRangeScanInitializeDSM().

◆ table_parallelscan_reinitialize()

static void table_parallelscan_reinitialize ( Relation  rel,
ParallelTableScanDesc  pscan 
)
inlinestatic

◆ table_relation_copy_data()

static void table_relation_copy_data ( Relation  rel,
const RelFileLocator newrlocator 
)
inlinestatic

◆ table_relation_copy_for_cluster()

static void table_relation_copy_for_cluster ( Relation  OldTable,
Relation  NewTable,
Relation  OldIndex,
bool  use_sort,
TransactionId  OldestXmin,
Snapshot  snapshot,
TransactionId xid_cutoff,
MultiXactId multi_cutoff,
double num_tuples,
double tups_vacuumed,
double tups_recently_dead 
)
inlinestatic

Definition at line 1748 of file tableam.h.

1758{
1759 OldTable->rd_tableam->relation_copy_for_cluster(OldTable, NewTable, OldIndex,
1760 use_sort, OldestXmin,
1761 snapshot,
1763 num_tuples, tups_vacuumed,
1765}

References fb().

Referenced by copy_table_data().

◆ table_relation_estimate_size()

static void table_relation_estimate_size ( Relation  rel,
int32 attr_widths,
BlockNumber pages,
double tuples,
double allvisfrac 
)
inlinestatic

Definition at line 2009 of file tableam.h.

2012{
2013 rel->rd_tableam->relation_estimate_size(rel, attr_widths, pages, tuples,
2014 allvisfrac);
2015}

References fb(), RelationData::rd_tableam, IndexFetchTableData::rel, and TableAmRoutine::relation_estimate_size.

Referenced by estimate_rel_size().

◆ table_relation_fetch_toast_slice()

static void table_relation_fetch_toast_slice ( Relation  toastrel,
Oid  valueid,
int32  attrsize,
int32  sliceoffset,
int32  slicelength,
varlena result 
)
inlinestatic

Definition at line 1988 of file tableam.h.

1991{
1992 toastrel->rd_tableam->relation_fetch_toast_slice(toastrel, valueid,
1993 attrsize,
1995 result);
1996}

References fb(), and result.

Referenced by toast_fetch_datum(), and toast_fetch_datum_slice().

◆ table_relation_needs_toast_table()

static bool table_relation_needs_toast_table ( Relation  rel)
inlinestatic

Definition at line 1949 of file tableam.h.

1950{
1951 return rel->rd_tableam->relation_needs_toast_table(rel);
1952}

References RelationData::rd_tableam, IndexFetchTableData::rel, and TableAmRoutine::relation_needs_toast_table.

Referenced by needs_toast_table().

◆ table_relation_nontransactional_truncate()

static void table_relation_nontransactional_truncate ( Relation  rel)
inlinestatic

◆ table_relation_set_new_filelocator()

static void table_relation_set_new_filelocator ( Relation  rel,
const RelFileLocator newrlocator,
char  persistence,
TransactionId freezeXid,
MultiXactId minmulti 
)
inlinestatic

◆ table_relation_size()

static uint64 table_relation_size ( Relation  rel,
ForkNumber  forkNumber 
)
inlinestatic

Definition at line 1940 of file tableam.h.

1941{
1942 return rel->rd_tableam->relation_size(rel, forkNumber);
1943}

References fb(), RelationData::rd_tableam, IndexFetchTableData::rel, and TableAmRoutine::relation_size.

Referenced by RelationGetNumberOfBlocksInFork().

◆ table_relation_toast_am()

static Oid table_relation_toast_am ( Relation  rel)
inlinestatic

Definition at line 1959 of file tableam.h.

1960{
1961 return rel->rd_tableam->relation_toast_am(rel);
1962}

References RelationData::rd_tableam, IndexFetchTableData::rel, and TableAmRoutine::relation_toast_am.

Referenced by create_toast_table().

◆ table_relation_vacuum()

static void table_relation_vacuum ( Relation  rel,
const VacuumParams params,
BufferAccessStrategy  bstrategy 
)
inlinestatic

Definition at line 1779 of file tableam.h.

1781{
1782 rel->rd_tableam->relation_vacuum(rel, params, bstrategy);
1783}

References RelationData::rd_tableam, IndexFetchTableData::rel, and TableAmRoutine::relation_vacuum.

Referenced by vacuum_rel().

◆ table_rescan()

static void table_rescan ( TableScanDesc  scan,
ScanKeyData key 
)
inlinestatic

◆ table_rescan_set_params()

static void table_rescan_set_params ( TableScanDesc  scan,
ScanKeyData key,
bool  allow_strat,
bool  allow_sync,
bool  allow_pagemode 
)
inlinestatic

Definition at line 1084 of file tableam.h.

1086{
1087 scan->rs_rd->rd_tableam->scan_rescan(scan, key, true,
1090}

References fb(), RelationData::rd_tableam, TableScanDescData::rs_rd, and TableAmRoutine::scan_rescan.

Referenced by tablesample_init().

◆ table_rescan_tidrange()

static void table_rescan_tidrange ( TableScanDesc  sscan,
ItemPointer  mintid,
ItemPointer  maxtid 
)
inlinestatic

Definition at line 1141 of file tableam.h.

1143{
1144 /* Ensure table_beginscan_tidrange() was used. */
1145 Assert((sscan->rs_flags & SO_TYPE_TIDRANGESCAN) != 0);
1146
1147 sscan->rs_rd->rd_tableam->scan_rescan(sscan, NULL, false, false, false, false);
1148 sscan->rs_rd->rd_tableam->scan_set_tidrange(sscan, mintid, maxtid);
1149}

References Assert, fb(), and SO_TYPE_TIDRANGESCAN.

Referenced by TidRangeNext().

◆ table_scan_analyze_next_block()

static bool table_scan_analyze_next_block ( TableScanDesc  scan,
ReadStream stream 
)
inlinestatic

Definition at line 1794 of file tableam.h.

1795{
1796 return scan->rs_rd->rd_tableam->scan_analyze_next_block(scan, stream);
1797}

References RelationData::rd_tableam, TableScanDescData::rs_rd, and TableAmRoutine::scan_analyze_next_block.

Referenced by acquire_sample_rows().

◆ table_scan_analyze_next_tuple()

static bool table_scan_analyze_next_tuple ( TableScanDesc  scan,
double liverows,
double deadrows,
TupleTableSlot slot 
)
inlinestatic

Definition at line 1810 of file tableam.h.

1813{
1814 return scan->rs_rd->rd_tableam->scan_analyze_next_tuple(scan,
1816 slot);
1817}

References fb(), RelationData::rd_tableam, TableScanDescData::rs_rd, and TableAmRoutine::scan_analyze_next_tuple.

Referenced by acquire_sample_rows().

◆ table_scan_bitmap_next_tuple()

static bool table_scan_bitmap_next_tuple ( TableScanDesc  scan,
TupleTableSlot slot,
bool recheck,
uint64 lossy_pages,
uint64 exact_pages 
)
inlinestatic

Definition at line 2037 of file tableam.h.

2042{
2043 return scan->rs_rd->rd_tableam->scan_bitmap_next_tuple(scan,
2044 slot,
2045 recheck,
2046 lossy_pages,
2047 exact_pages);
2048}

References RelationData::rd_tableam, TableScanDescData::rs_rd, and TableAmRoutine::scan_bitmap_next_tuple.

Referenced by BitmapHeapNext().

◆ table_scan_getnextslot()

static bool table_scan_getnextslot ( TableScanDesc  sscan,
ScanDirection  direction,
TupleTableSlot slot 
)
inlinestatic

◆ table_scan_getnextslot_tidrange()

static bool table_scan_getnextslot_tidrange ( TableScanDesc  sscan,
ScanDirection  direction,
TupleTableSlot slot 
)
inlinestatic

Definition at line 1157 of file tableam.h.

1159{
1160 /* Ensure table_beginscan_tidrange() was used. */
1161 Assert((sscan->rs_flags & SO_TYPE_TIDRANGESCAN) != 0);
1162
1163 /* We don't expect actual scans using NoMovementScanDirection */
1164 Assert(direction == ForwardScanDirection ||
1165 direction == BackwardScanDirection);
1166
1167 return sscan->rs_rd->rd_tableam->scan_getnextslot_tidrange(sscan,
1168 direction,
1169 slot);
1170}

References Assert, BackwardScanDirection, fb(), ForwardScanDirection, and SO_TYPE_TIDRANGESCAN.

Referenced by TidRangeNext().

◆ table_scan_sample_next_block()

static bool table_scan_sample_next_block ( TableScanDesc  scan,
SampleScanState scanstate 
)
inlinestatic

Definition at line 2060 of file tableam.h.

2062{
2063 return scan->rs_rd->rd_tableam->scan_sample_next_block(scan, scanstate);
2064}

References fb(), RelationData::rd_tableam, TableScanDescData::rs_rd, and TableAmRoutine::scan_sample_next_block.

Referenced by tablesample_getnext().

◆ table_scan_sample_next_tuple()

static bool table_scan_sample_next_tuple ( TableScanDesc  scan,
SampleScanState scanstate,
TupleTableSlot slot 
)
inlinestatic

Definition at line 2075 of file tableam.h.

2078{
2079 return scan->rs_rd->rd_tableam->scan_sample_next_tuple(scan, scanstate,
2080 slot);
2081}

References fb(), RelationData::rd_tableam, TableScanDescData::rs_rd, and TableAmRoutine::scan_sample_next_tuple.

Referenced by tablesample_getnext().

◆ table_slot_callbacks()

const TupleTableSlotOps * table_slot_callbacks ( Relation  relation)
extern

Definition at line 59 of file tableam.c.

60{
62
63 if (relation->rd_tableam)
64 tts_cb = relation->rd_tableam->slot_callbacks(relation);
65 else if (relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
66 {
67 /*
68 * Historically FDWs expect to store heap tuples in slots. Continue
69 * handing them one, to make it less painful to adapt FDWs to new
70 * versions. The cost of a heap slot over a virtual slot is pretty
71 * small.
72 */
74 }
75 else
76 {
77 /*
78 * These need to be supported, as some parts of the code (like COPY)
79 * need to create slots for such relations too. It seems better to
80 * centralize the knowledge that a heap slot is the right thing in
81 * that case here.
82 */
83 Assert(relation->rd_rel->relkind == RELKIND_VIEW ||
84 relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
86 }
87
88 return tts_cb;
89}
const TupleTableSlotOps TTSOpsVirtual
Definition execTuples.c:84
const TupleTableSlotOps TTSOpsHeapTuple
Definition execTuples.c:85
const TupleTableSlotOps *(* slot_callbacks)(Relation rel)
Definition tableam.h:335

References Assert, fb(), RelationData::rd_rel, RelationData::rd_tableam, TableAmRoutine::slot_callbacks, TTSOpsHeapTuple, and TTSOpsVirtual.

Referenced by apply_concurrent_changes(), ATRewriteTable(), ExecGetAllNullSlot(), ExecGetReturningSlot(), ExecGetTriggerNewSlot(), ExecGetTriggerOldSlot(), ExecInitBitmapHeapScan(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), ExecInitSampleScan(), ExecInitSeqScan(), ExecInitTidRangeScan(), ExecInitTidScan(), and table_slot_create().

◆ table_slot_create()

TupleTableSlot * table_slot_create ( Relation  relation,
List **  reglist 
)
extern

Definition at line 92 of file tableam.c.

93{
95 TupleTableSlot *slot;
96
97 tts_cb = table_slot_callbacks(relation);
99
100 if (reglist)
101 *reglist = lappend(*reglist, slot);
102
103 return slot;
104}
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
List * lappend(List *list, void *datum)
Definition list.c:339
#define RelationGetDescr(relation)
Definition rel.h:542
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition tableam.c:59

References fb(), lappend(), MakeSingleTupleTableSlot(), RelationGetDescr, and table_slot_callbacks().

Referenced by acquire_sample_rows(), apply_handle_tuple_routing(), apply_handle_update_internal(), build_index_value_desc(), check_default_partition_contents(), check_exclusion_or_unique_constraint(), CopyFrom(), CopyMultiInsertInfoNextFreeSlot(), CopyRelationTo(), createSplitPartitionContext(), EvalPlanQualSlot(), ExecCrossPartitionUpdate(), ExecForPortionOfLeftovers(), ExecInitInsertProjection(), ExecInitMerge(), ExecInitMergeTupleSlots(), ExecInitModifyTable(), ExecInitPartitionInfo(), ExecInitRoutingInfo(), ExecInitUpdateProjection(), FindConflictTuple(), FindReplTupleInLocalRel(), get_actual_variable_range(), heap_entry_is_visible(), heapam_index_build_range_scan(), heapam_relation_copy_for_cluster(), IndexCheckExclusion(), MergePartitionsMoveRows(), RelationFindDeletedTupleInfoByIndex(), RelationFindDeletedTupleInfoSeq(), RelationFindReplTupleSeq(), ri_FastPathCheck(), ri_FastPathGetEntry(), SplitPartitionMoveRows(), systable_beginscan(), systable_beginscan_ordered(), table_index_fetch_tuple_check(), unique_key_recheck(), validateDomainCheckConstraint(), validateDomainNotNullConstraint(), and validateForeignKeyConstraint().

◆ table_tuple_complete_speculative()

static void table_tuple_complete_speculative ( Relation  rel,
TupleTableSlot slot,
uint32  specToken,
bool  succeeded 
)
inlinestatic

Definition at line 1491 of file tableam.h.

1493{
1495 succeeded);
1496}

References fb(), RelationData::rd_tableam, IndexFetchTableData::rel, and TableAmRoutine::tuple_complete_speculative.

Referenced by ExecInsert().

◆ table_tuple_delete()

static TM_Result table_tuple_delete ( Relation  rel,
ItemPointer  tid,
CommandId  cid,
uint32  options,
Snapshot  snapshot,
Snapshot  crosscheck,
bool  wait,
TM_FailureData tmfd 
)
inlinestatic

Definition at line 1549 of file tableam.h.

1552{
1553 return rel->rd_tableam->tuple_delete(rel, tid, cid, options,
1554 snapshot, crosscheck,
1555 wait, tmfd);
1556}

References fb(), RelationData::rd_tableam, IndexFetchTableData::rel, and TableAmRoutine::tuple_delete.

Referenced by apply_concurrent_delete(), ExecDeleteAct(), and simple_table_tuple_delete().

◆ table_tuple_fetch_row_version()

static bool table_tuple_fetch_row_version ( Relation  rel,
ItemPointer  tid,
Snapshot  snapshot,
TupleTableSlot slot 
)
inlinestatic

Definition at line 1344 of file tableam.h.

1348{
1349 /*
1350 * We don't expect direct calls to table_tuple_fetch_row_version with
1351 * valid CheckXidAlive for catalog or regular tables. See detailed
1352 * comments in xact.c where these variables are declared.
1353 */
1355 elog(ERROR, "unexpected table_tuple_fetch_row_version call during logical decoding");
1356
1357 return rel->rd_tableam->tuple_fetch_row_version(rel, tid, snapshot, slot);
1358}

References bsysscan, CheckXidAlive, elog, ERROR, RelationData::rd_tableam, IndexFetchTableData::rel, TransactionIdIsValid, TableAmRoutine::tuple_fetch_row_version, and unlikely.

Referenced by AfterTriggerExecute(), EvalPlanQualFetchRowMark(), ExecCheckTIDVisible(), ExecCrossPartitionUpdate(), ExecDelete(), ExecForPortionOfLeftovers(), ExecMergeMatched(), ExecModifyTable(), ExecOnConflictSelect(), ExecUpdate(), GetTupleForTrigger(), heap_entry_is_visible(), and TidNext().

◆ table_tuple_get_latest_tid()

void table_tuple_get_latest_tid ( TableScanDesc  scan,
ItemPointer  tid 
)
extern

Definition at line 269 of file tableam.c.

270{
271 Relation rel = scan->rs_rd;
272 const TableAmRoutine *tableam = rel->rd_tableam;
273
274 /*
275 * Since this can be called with user-supplied TID, don't trust the input
276 * too much.
277 */
278 if (!tableam->tuple_tid_valid(scan, tid))
281 errmsg("tid (%u, %u) is not valid for relation \"%s\"",
285
286 tableam->tuple_get_latest_tid(scan, tid);
287}
int errcode(int sqlerrcode)
Definition elog.c:874
#define ereport(elevel,...)
Definition elog.h:152
static OffsetNumber ItemPointerGetOffsetNumberNoCheck(const ItemPointerData *pointer)
Definition itemptr.h:114
static BlockNumber ItemPointerGetBlockNumberNoCheck(const ItemPointerData *pointer)
Definition itemptr.h:93
static char * errmsg
#define RelationGetRelationName(relation)
Definition rel.h:550

References ereport, errcode(), errmsg, ERROR, fb(), ItemPointerGetBlockNumberNoCheck(), ItemPointerGetOffsetNumberNoCheck(), RelationData::rd_tableam, RelationGetRelationName, TableScanDescData::rs_rd, TableAmRoutine::tuple_get_latest_tid, and TableAmRoutine::tuple_tid_valid.

Referenced by currtid_internal(), and TidNext().

◆ table_tuple_insert()

◆ table_tuple_insert_speculative()

static void table_tuple_insert_speculative ( Relation  rel,
TupleTableSlot slot,
CommandId  cid,
uint32  options,
BulkInsertStateData bistate,
uint32  specToken 
)
inlinestatic

Definition at line 1477 of file tableam.h.

1481{
1483 bistate, specToken);
1484}

References fb(), RelationData::rd_tableam, IndexFetchTableData::rel, and TableAmRoutine::tuple_insert_speculative.

Referenced by ExecInsert().

◆ table_tuple_lock()

static TM_Result table_tuple_lock ( Relation  rel,
ItemPointer  tid,
Snapshot  snapshot,
TupleTableSlot slot,
CommandId  cid,
LockTupleMode  mode,
LockWaitPolicy  wait_policy,
uint8  flags,
TM_FailureData tmfd 
)
inlinestatic

◆ table_tuple_satisfies_snapshot()

static bool table_tuple_satisfies_snapshot ( Relation  rel,
TupleTableSlot slot,
Snapshot  snapshot 
)
inlinestatic

◆ table_tuple_tid_valid()

static bool table_tuple_tid_valid ( TableScanDesc  scan,
ItemPointer  tid 
)
inlinestatic

Definition at line 1370 of file tableam.h.

1371{
1372 return scan->rs_rd->rd_tableam->tuple_tid_valid(scan, tid);
1373}

References RelationData::rd_tableam, TableScanDescData::rs_rd, and TableAmRoutine::tuple_tid_valid.

Referenced by TidListEval().

◆ table_tuple_update()

static TM_Result table_tuple_update ( Relation  rel,
ItemPointer  otid,
TupleTableSlot slot,
CommandId  cid,
uint32  options,
Snapshot  snapshot,
Snapshot  crosscheck,
bool  wait,
TM_FailureData tmfd,
LockTupleMode lockmode,
TU_UpdateIndexes update_indexes 
)
inlinestatic

Definition at line 1600 of file tableam.h.

1605{
1606 return rel->rd_tableam->tuple_update(rel, otid, slot,
1607 cid, options, snapshot, crosscheck,
1608 wait, tmfd,
1609 lockmode, update_indexes);
1610}

References fb(), RelationData::rd_tableam, IndexFetchTableData::rel, and TableAmRoutine::tuple_update.

Referenced by apply_concurrent_update(), ExecUpdateAct(), and simple_table_tuple_update().

Variable Documentation

◆ default_table_access_method

PGDLLIMPORT char* default_table_access_method
extern

Definition at line 49 of file tableam.c.

Referenced by ATPrepSetAccessMethod(), and DefineRelation().

◆ synchronize_seqscans

PGDLLIMPORT bool synchronize_seqscans
extern

Definition at line 50 of file tableam.c.

Referenced by initscan(), and table_block_parallelscan_initialize().