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. */ |
25 | struct IndexInfo; |
26 | |
27 | /* |
28 | * Struct for statistics returned by ambuild |
29 | */ |
30 | typedef 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 | */ |
44 | typedef 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 | */ |
72 | typedef 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 */ |
84 | typedef bool (*IndexBulkDeleteCallback) (ItemPointer itemptr, void *state); |
85 | |
86 | /* struct definitions appear in relscan.h */ |
87 | typedef struct IndexScanDescData *IndexScanDesc; |
88 | typedef struct SysScanDescData *SysScanDesc; |
89 | |
90 | typedef 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 | */ |
112 | typedef 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 */ |
122 | typedef 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 | |
138 | extern Relation index_open(Oid relationId, LOCKMODE lockmode); |
139 | extern void index_close(Relation relation, LOCKMODE lockmode); |
140 | |
141 | extern 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 | |
148 | extern IndexScanDesc index_beginscan(Relation heapRelation, |
149 | Relation indexRelation, |
150 | Snapshot snapshot, |
151 | int nkeys, int norderbys); |
152 | extern IndexScanDesc index_beginscan_bitmap(Relation indexRelation, |
153 | Snapshot snapshot, |
154 | int nkeys); |
155 | extern void index_rescan(IndexScanDesc scan, |
156 | ScanKey keys, int nkeys, |
157 | ScanKey orderbys, int norderbys); |
158 | extern void index_endscan(IndexScanDesc scan); |
159 | extern void index_markpos(IndexScanDesc scan); |
160 | extern void index_restrpos(IndexScanDesc scan); |
161 | extern Size index_parallelscan_estimate(Relation indexrel, Snapshot snapshot); |
162 | extern void index_parallelscan_initialize(Relation heaprel, Relation indexrel, |
163 | Snapshot snapshot, ParallelIndexScanDesc target); |
164 | extern void index_parallelrescan(IndexScanDesc scan); |
165 | extern IndexScanDesc index_beginscan_parallel(Relation heaprel, |
166 | Relation indexrel, int nkeys, int norderbys, |
167 | ParallelIndexScanDesc pscan); |
168 | extern ItemPointer index_getnext_tid(IndexScanDesc scan, |
169 | ScanDirection direction); |
170 | struct TupleTableSlot; |
171 | extern bool index_fetch_heap(IndexScanDesc scan, struct TupleTableSlot *slot); |
172 | extern bool index_getnext_slot(IndexScanDesc scan, ScanDirection direction, |
173 | struct TupleTableSlot *slot); |
174 | extern int64 index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap); |
175 | |
176 | extern IndexBulkDeleteResult *index_bulk_delete(IndexVacuumInfo *info, |
177 | IndexBulkDeleteResult *stats, |
178 | IndexBulkDeleteCallback callback, |
179 | void *callback_state); |
180 | extern IndexBulkDeleteResult *index_vacuum_cleanup(IndexVacuumInfo *info, |
181 | IndexBulkDeleteResult *stats); |
182 | extern bool index_can_return(Relation indexRelation, int attno); |
183 | extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum, |
184 | uint16 procnum); |
185 | extern FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attnum, |
186 | uint16 procnum); |
187 | extern 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 | */ |
195 | extern IndexScanDesc RelationGetIndexScan(Relation indexRelation, |
196 | int nkeys, int norderbys); |
197 | extern void IndexScanEnd(IndexScanDesc scan); |
198 | extern char *BuildIndexValueDescription(Relation indexRelation, |
199 | Datum *values, bool *isnull); |
200 | extern 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 | */ |
209 | extern SysScanDesc systable_beginscan(Relation heapRelation, |
210 | Oid indexId, |
211 | bool indexOK, |
212 | Snapshot snapshot, |
213 | int nkeys, ScanKey key); |
214 | extern HeapTuple systable_getnext(SysScanDesc sysscan); |
215 | extern bool systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup); |
216 | extern void systable_endscan(SysScanDesc sysscan); |
217 | extern SysScanDesc systable_beginscan_ordered(Relation heapRelation, |
218 | Relation indexRelation, |
219 | Snapshot snapshot, |
220 | int nkeys, ScanKey key); |
221 | extern HeapTuple systable_getnext_ordered(SysScanDesc sysscan, |
222 | ScanDirection direction); |
223 | extern void systable_endscan_ordered(SysScanDesc sysscan); |
224 | |
225 | #endif /* GENAM_H */ |
226 | |