| 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 | |