PostgreSQL Source Code git master
tableamapi.c
Go to the documentation of this file.
1/*----------------------------------------------------------------------
2 *
3 * tableamapi.c
4 * Support routines for API for Postgres table access methods
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 * src/backend/access/table/tableamapi.c
10 *----------------------------------------------------------------------
11 */
12#include "postgres.h"
13
14#include "access/tableam.h"
15#include "access/xact.h"
16#include "commands/defrem.h"
17#include "miscadmin.h"
18#include "utils/guc_hooks.h"
19
20
21/*
22 * GetTableAmRoutine
23 * Call the specified access method handler routine to get its
24 * TableAmRoutine struct, which will be palloc'd in the caller's
25 * memory context.
26 */
27const TableAmRoutine *
29{
30 Datum datum;
31 const TableAmRoutine *routine;
32
33 datum = OidFunctionCall0(amhandler);
34 routine = (TableAmRoutine *) DatumGetPointer(datum);
35
36 if (routine == NULL || !IsA(routine, TableAmRoutine))
37 elog(ERROR, "table access method handler %u did not return a TableAmRoutine struct",
38 amhandler);
39
40 /*
41 * Assert that all required callbacks are present. That makes it a bit
42 * easier to keep AMs up to date, e.g. when forward porting them to a new
43 * major version.
44 */
45 Assert(routine->scan_begin != NULL);
46 Assert(routine->scan_end != NULL);
47 Assert(routine->scan_rescan != NULL);
48 Assert(routine->scan_getnextslot != NULL);
49
50 Assert(routine->parallelscan_estimate != NULL);
51 Assert(routine->parallelscan_initialize != NULL);
52 Assert(routine->parallelscan_reinitialize != NULL);
53
54 Assert(routine->index_fetch_begin != NULL);
55 Assert(routine->index_fetch_reset != NULL);
56 Assert(routine->index_fetch_end != NULL);
57 Assert(routine->index_fetch_tuple != NULL);
58
59 Assert(routine->tuple_fetch_row_version != NULL);
60 Assert(routine->tuple_tid_valid != NULL);
61 Assert(routine->tuple_get_latest_tid != NULL);
62 Assert(routine->tuple_satisfies_snapshot != NULL);
63 Assert(routine->index_delete_tuples != NULL);
64
65 Assert(routine->tuple_insert != NULL);
66
67 /*
68 * Could be made optional, but would require throwing error during
69 * parse-analysis.
70 */
71 Assert(routine->tuple_insert_speculative != NULL);
72 Assert(routine->tuple_complete_speculative != NULL);
73
74 Assert(routine->multi_insert != NULL);
75 Assert(routine->tuple_delete != NULL);
76 Assert(routine->tuple_update != NULL);
77 Assert(routine->tuple_lock != NULL);
78
79 Assert(routine->relation_set_new_filelocator != NULL);
81 Assert(routine->relation_copy_data != NULL);
82 Assert(routine->relation_copy_for_cluster != NULL);
83 Assert(routine->relation_vacuum != NULL);
84 Assert(routine->scan_analyze_next_block != NULL);
85 Assert(routine->scan_analyze_next_tuple != NULL);
86 Assert(routine->index_build_range_scan != NULL);
87 Assert(routine->index_validate_scan != NULL);
88
89 Assert(routine->relation_size != NULL);
90 Assert(routine->relation_needs_toast_table != NULL);
91
92 Assert(routine->relation_estimate_size != NULL);
93
94 /* optional, but one callback implies presence of the other */
95 Assert((routine->scan_bitmap_next_block == NULL) ==
96 (routine->scan_bitmap_next_tuple == NULL));
97 Assert(routine->scan_sample_next_block != NULL);
98 Assert(routine->scan_sample_next_tuple != NULL);
99
100 return routine;
101}
102
103/* check_hook: validate new default_table_access_method */
104bool
106{
107 if (**newval == '\0')
108 {
109 GUC_check_errdetail("\"%s\" cannot be empty.",
110 "default_table_access_method");
111 return false;
112 }
113
114 if (strlen(*newval) >= NAMEDATALEN)
115 {
116 GUC_check_errdetail("\"%s\" is too long (maximum %d characters).",
117 "default_table_access_method", NAMEDATALEN - 1);
118 return false;
119 }
120
121 /*
122 * If we aren't inside a transaction, or not connected to a database, we
123 * cannot do the catalog access necessary to verify the method. Must
124 * accept the value on faith.
125 */
127 {
128 if (!OidIsValid(get_table_am_oid(*newval, true)))
129 {
130 /*
131 * When source == PGC_S_TEST, don't throw a hard error for a
132 * nonexistent table access method, only a NOTICE. See comments in
133 * guc.h.
134 */
135 if (source == PGC_S_TEST)
136 {
138 (errcode(ERRCODE_UNDEFINED_OBJECT),
139 errmsg("table access method \"%s\" does not exist",
140 *newval)));
141 }
142 else
143 {
144 GUC_check_errdetail("Table access method \"%s\" does not exist.",
145 *newval);
146 return false;
147 }
148 }
149 }
150
151 return true;
152}
Oid get_table_am_oid(const char *amname, bool missing_ok)
Definition: amcmds.c:173
#define Assert(condition)
Definition: c.h:815
#define OidIsValid(objectId)
Definition: c.h:732
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define NOTICE
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:149
#define OidFunctionCall0(functionId)
Definition: fmgr.h:677
Oid MyDatabaseId
Definition: globals.c:93
#define newval
#define GUC_check_errdetail
Definition: guc.h:476
GucSource
Definition: guc.h:108
@ PGC_S_TEST
Definition: guc.h:121
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define NAMEDATALEN
static rewind_source * source
Definition: pg_rewind.c:89
uintptr_t Datum
Definition: postgres.h:69
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
#define InvalidOid
Definition: postgres_ext.h:37
unsigned int Oid
Definition: postgres_ext.h:32
Size(* parallelscan_initialize)(Relation rel, ParallelTableScanDesc pscan)
Definition: tableam.h:399
void(* relation_copy_data)(Relation rel, const RelFileLocator *newrlocator)
Definition: tableam.h:623
bool(* scan_sample_next_tuple)(TableScanDesc scan, struct SampleScanState *scanstate, TupleTableSlot *slot)
Definition: tableam.h:876
void(* index_fetch_reset)(struct IndexFetchTableData *data)
Definition: tableam.h:429
void(* tuple_complete_speculative)(Relation rel, TupleTableSlot *slot, uint32 specToken, bool succeeded)
Definition: tableam.h:523
void(* parallelscan_reinitialize)(Relation rel, ParallelTableScanDesc pscan)
Definition: tableam.h:406
void(* tuple_get_latest_tid)(TableScanDesc scan, ItemPointer tid)
Definition: tableam.h:488
void(* relation_copy_for_cluster)(Relation OldTable, Relation NewTable, Relation OldIndex, bool use_sort, TransactionId OldestXmin, TransactionId *xid_cutoff, MultiXactId *multi_cutoff, double *num_tuples, double *tups_vacuumed, double *tups_recently_dead)
Definition: tableam.h:627
void(* relation_estimate_size)(Relation rel, int32 *attr_widths, BlockNumber *pages, double *tuples, double *allvisfrac)
Definition: tableam.h:771
double(* index_build_range_scan)(Relation table_rel, Relation index_rel, struct 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:692
TableScanDesc(* scan_begin)(Relation rel, Snapshot snapshot, int nkeys, struct ScanKeyData *key, ParallelTableScanDesc pscan, uint32 flags)
Definition: tableam.h:327
bool(* relation_needs_toast_table)(Relation rel)
Definition: tableam.h:735
bool(* scan_bitmap_next_block)(TableScanDesc scan, BlockNumber *blockno, bool *recheck, uint64 *lossy_pages, uint64 *exact_pages)
Definition: tableam.h:819
bool(* tuple_tid_valid)(TableScanDesc scan, ItemPointer tid)
Definition: tableam.h:481
void(* multi_insert)(Relation rel, TupleTableSlot **slots, int nslots, CommandId cid, int options, struct BulkInsertStateData *bistate)
Definition: tableam.h:529
bool(* scan_bitmap_next_tuple)(TableScanDesc scan, TupleTableSlot *slot)
Definition: tableam.h:832
void(* scan_end)(TableScanDesc scan)
Definition: tableam.h:337
uint64(* relation_size)(Relation rel, ForkNumber forkNumber)
Definition: tableam.h:725
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:555
bool(* scan_sample_next_block)(TableScanDesc scan, struct SampleScanState *scanstate)
Definition: tableam.h:860
void(* relation_nontransactional_truncate)(Relation rel)
Definition: tableam.h:615
TM_Result(* tuple_update)(Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes)
Definition: tableam.h:543
void(* tuple_insert)(Relation rel, TupleTableSlot *slot, CommandId cid, int options, struct BulkInsertStateData *bistate)
Definition: tableam.h:510
void(* scan_rescan)(TableScanDesc scan, struct ScanKeyData *key, bool set_params, bool allow_strat, bool allow_sync, bool allow_pagemode)
Definition: tableam.h:343
bool(* tuple_fetch_row_version)(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot)
Definition: tableam.h:473
void(* relation_vacuum)(Relation rel, struct VacuumParams *params, BufferAccessStrategy bstrategy)
Definition: tableam.h:653
bool(* scan_analyze_next_block)(TableScanDesc scan, ReadStream *stream)
Definition: tableam.h:674
Size(* parallelscan_estimate)(Relation rel)
Definition: tableam.h:392
void(* relation_set_new_filelocator)(Relation rel, const RelFileLocator *newrlocator, char persistence, TransactionId *freezeXid, MultiXactId *minmulti)
Definition: tableam.h:601
struct IndexFetchTableData *(* index_fetch_begin)(Relation rel)
Definition: tableam.h:423
bool(* scan_analyze_next_tuple)(TableScanDesc scan, TransactionId OldestXmin, double *liverows, double *deadrows, TupleTableSlot *slot)
Definition: tableam.h:685
TransactionId(* index_delete_tuples)(Relation rel, TM_IndexDeleteOp *delstate)
Definition: tableam.h:500
void(* index_fetch_end)(struct IndexFetchTableData *data)
Definition: tableam.h:434
bool(* index_fetch_tuple)(struct IndexFetchTableData *scan, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot, bool *call_again, bool *all_dead)
Definition: tableam.h:456
void(* tuple_insert_speculative)(Relation rel, TupleTableSlot *slot, CommandId cid, int options, struct BulkInsertStateData *bistate, uint32 specToken)
Definition: tableam.h:515
TM_Result(* tuple_delete)(Relation rel, ItemPointer tid, CommandId cid, Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, bool changingPart)
Definition: tableam.h:533
void(* index_validate_scan)(Relation table_rel, Relation index_rel, struct IndexInfo *index_info, Snapshot snapshot, struct ValidateIndexState *state)
Definition: tableam.h:705
bool(* scan_getnextslot)(TableScanDesc scan, ScanDirection direction, TupleTableSlot *slot)
Definition: tableam.h:350
bool(* tuple_satisfies_snapshot)(Relation rel, TupleTableSlot *slot, Snapshot snapshot)
Definition: tableam.h:495
bool check_default_table_access_method(char **newval, void **extra, GucSource source)
Definition: tableamapi.c:105
const TableAmRoutine * GetTableAmRoutine(Oid amhandler)
Definition: tableamapi.c:28
bool IsTransactionState(void)
Definition: xact.c:386