1/*-------------------------------------------------------------------------
2 *
3 * genam.h
4 * POSTGRES generalized index access method definitions.
5 *
6 *
7 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
9 *
10 * src/include/access/genam.h
11 *
12 *-------------------------------------------------------------------------
13 */
14#ifndef GENAM_H
15#define GENAM_H
16
17#include "access/sdir.h"
18#include "access/skey.h"
19#include "nodes/tidbitmap.h"
20#include "storage/lockdefs.h"
21#include "utils/relcache.h"
22#include "utils/snapshot.h"
23
24/* We don't want this file to depend on execnodes.h. */
25struct IndexInfo;
26
27/*
28 * Struct for statistics returned by ambuild
29 */
30typedef struct IndexBuildResult
31{
32 double heap_tuples; /* # of tuples seen in parent table */
33 double index_tuples; /* # of tuples inserted into index */
34} IndexBuildResult;
35
36/*
37 * Struct for input arguments passed to ambulkdelete and amvacuumcleanup
38 *
39 * num_heap_tuples is accurate only when estimated_count is false;
40 * otherwise it's just an estimate (currently, the estimate is the
41 * prior value of the relation's pg_class.reltuples field). It will
42 * always just be an estimate during ambulkdelete.
43 */
44typedef struct IndexVacuumInfo
45{
46 Relation index; /* the index being vacuumed */
47 bool analyze_only; /* ANALYZE (without any actual vacuum) */
48 bool report_progress; /* emit progress.h status reports */
49 bool estimated_count; /* num_heap_tuples is an estimate */
50 int message_level; /* ereport level for progress messages */
51 double num_heap_tuples; /* tuples remaining in heap */
52 BufferAccessStrategy strategy; /* access strategy for reads */
53} IndexVacuumInfo;
54
55/*
56 * Struct for statistics returned by ambulkdelete and amvacuumcleanup
57 *
58 * This struct is normally allocated by the first ambulkdelete call and then
59 * passed along through subsequent ones until amvacuumcleanup; however,
60 * amvacuumcleanup must be prepared to allocate it in the case where no
61 * ambulkdelete calls were made (because no tuples needed deletion).
62 * Note that an index AM could choose to return a larger struct
63 * of which this is just the first field; this provides a way for ambulkdelete
64 * to communicate additional private data to amvacuumcleanup.
65 *
66 * Note: pages_removed is the amount by which the index physically shrank,
67 * if any (ie the change in its total size on disk). pages_deleted and
68 * pages_free refer to free space within the index file. Some index AMs
69 * may compute num_index_tuples by reference to num_heap_tuples, in which
70 * case they should copy the estimated_count field from IndexVacuumInfo.
71 */
72typedef struct IndexBulkDeleteResult
73{
74 BlockNumber num_pages; /* pages remaining in index */
75 BlockNumber pages_removed; /* # removed during vacuum operation */
76 bool estimated_count; /* num_index_tuples is an estimate */
77 double num_index_tuples; /* tuples remaining */
78 double tuples_removed; /* # removed during vacuum operation */
79 BlockNumber pages_deleted; /* # unused pages in index */
80 BlockNumber pages_free; /* # pages available for reuse */
81} IndexBulkDeleteResult;
82
83/* Typedef for callback function to determine if a tuple is bulk-deletable */
84typedef bool (*IndexBulkDeleteCallback) (ItemPointer itemptr, void *state);
85
86/* struct definitions appear in relscan.h */
87typedef struct IndexScanDescData *IndexScanDesc;
88typedef struct SysScanDescData *SysScanDesc;
89
90typedef struct ParallelIndexScanDescData *ParallelIndexScanDesc;
91
92/*
93 * Enumeration specifying the type of uniqueness check to perform in
94 * index_insert().
95 *
96 * UNIQUE_CHECK_YES is the traditional Postgres immediate check, possibly
97 * blocking to see if a conflicting transaction commits.
98 *
99 * For deferrable unique constraints, UNIQUE_CHECK_PARTIAL is specified at
100 * insertion time. The index AM should test if the tuple is unique, but
101 * should not throw error, block, or prevent the insertion if the tuple
102 * appears not to be unique. We'll recheck later when it is time for the
103 * constraint to be enforced. The AM must return true if the tuple is
104 * known unique, false if it is possibly non-unique. In the "true" case
105 * it is safe to omit the later recheck.
106 *
107 * When it is time to recheck the deferred constraint, a pseudo-insertion
108 * call is made with UNIQUE_CHECK_EXISTING. The tuple is already in the
109 * index in this case, so it should not be inserted again. Rather, just
110 * check for conflicting live tuples (possibly blocking).
111 */
112typedef enum IndexUniqueCheck
113{
114 UNIQUE_CHECK_NO, /* Don't do any uniqueness checking */
115 UNIQUE_CHECK_YES, /* Enforce uniqueness at insertion time */
116 UNIQUE_CHECK_PARTIAL, /* Test uniqueness, but no error */
117 UNIQUE_CHECK_EXISTING /* Check if existing tuple is unique */
118} IndexUniqueCheck;
119
120
121/* Nullable "ORDER BY col op const" distance */
122typedef struct IndexOrderByDistance
123{
124 double value;
125 bool isnull;
126} IndexOrderByDistance;
127
128/*
129 * generalized index_ interface routines (in indexam.c)
130 */
131
132/*
133 * IndexScanIsValid
134 * True iff the index scan is valid.
135 */
136#define IndexScanIsValid(scan) PointerIsValid(scan)
137
138extern Relation index_open(Oid relationId, LOCKMODE lockmode);
139extern void index_close(Relation relation, LOCKMODE lockmode);
140
141extern bool index_insert(Relation indexRelation,
142 Datum *values, bool *isnull,
143 ItemPointer heap_t_ctid,
144 Relation heapRelation,
145 IndexUniqueCheck checkUnique,
146 struct IndexInfo *indexInfo);
147
148extern IndexScanDesc index_beginscan(Relation heapRelation,
149 Relation indexRelation,
150 Snapshot snapshot,
151 int nkeys, int norderbys);
152extern IndexScanDesc index_beginscan_bitmap(Relation indexRelation,
153 Snapshot snapshot,
154 int nkeys);
155extern void index_rescan(IndexScanDesc scan,
156 ScanKey keys, int nkeys,
157 ScanKey orderbys, int norderbys);
158extern void index_endscan(IndexScanDesc scan);
159extern void index_markpos(IndexScanDesc scan);
160extern void index_restrpos(IndexScanDesc scan);
161extern Size index_parallelscan_estimate(Relation indexrel, Snapshot snapshot);
162extern void index_parallelscan_initialize(Relation heaprel, Relation indexrel,
163 Snapshot snapshot, ParallelIndexScanDesc target);
164extern void index_parallelrescan(IndexScanDesc scan);
165extern IndexScanDesc index_beginscan_parallel(Relation heaprel,
166 Relation indexrel, int nkeys, int norderbys,
167 ParallelIndexScanDesc pscan);
168extern ItemPointer index_getnext_tid(IndexScanDesc scan,
169 ScanDirection direction);
170struct TupleTableSlot;
171extern bool index_fetch_heap(IndexScanDesc scan, struct TupleTableSlot *slot);
172extern bool index_getnext_slot(IndexScanDesc scan, ScanDirection direction,
173 struct TupleTableSlot *slot);
174extern int64 index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap);
175
176extern IndexBulkDeleteResult *index_bulk_delete(IndexVacuumInfo *info,
177 IndexBulkDeleteResult *stats,
178 IndexBulkDeleteCallback callback,
179 void *callback_state);
180extern IndexBulkDeleteResult *index_vacuum_cleanup(IndexVacuumInfo *info,
181 IndexBulkDeleteResult *stats);
182extern bool index_can_return(Relation indexRelation, int attno);
183extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum,
184 uint16 procnum);
185extern FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attnum,
186 uint16 procnum);
187extern void index_store_float8_orderby_distances(IndexScanDesc scan,
188 Oid *orderByTypes,
189 IndexOrderByDistance *distances,
190 bool recheckOrderBy);
191
192/*
193 * index access method support routines (in genam.c)
194 */
195extern IndexScanDesc RelationGetIndexScan(Relation indexRelation,
196 int nkeys, int norderbys);
197extern void IndexScanEnd(IndexScanDesc scan);
198extern char *BuildIndexValueDescription(Relation indexRelation,
199 Datum *values, bool *isnull);
200extern TransactionId index_compute_xid_horizon_for_tuples(Relation irel,
201 Relation hrel,
202 Buffer ibuf,
203 OffsetNumber *itemnos,
204 int nitems);
205
206/*
207 * heap-or-index access to system catalogs (in genam.c)
208 */
209extern SysScanDesc systable_beginscan(Relation heapRelation,
210 Oid indexId,
211 bool indexOK,
212 Snapshot snapshot,
213 int nkeys, ScanKey key);
214extern HeapTuple systable_getnext(SysScanDesc sysscan);
215extern bool systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup);
216extern void systable_endscan(SysScanDesc sysscan);
217extern SysScanDesc systable_beginscan_ordered(Relation heapRelation,
218 Relation indexRelation,
219 Snapshot snapshot,
220 int nkeys, ScanKey key);
221extern HeapTuple systable_getnext_ordered(SysScanDesc sysscan,
222 ScanDirection direction);
223extern void systable_endscan_ordered(SysScanDesc sysscan);
224
225#endif /* GENAM_H */
226