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