1 /*-------------------------------------------------------------------------
2  *
3  * amapi.h
4  *	  API for Postgres index access methods.
5  *
6  * Copyright (c) 2015-2018, PostgreSQL Global Development Group
7  *
8  * src/include/access/amapi.h
9  *
10  *-------------------------------------------------------------------------
11  */
12 #ifndef AMAPI_H
13 #define AMAPI_H
14 
15 #include "access/genam.h"
16 
17 /*
18  * We don't wish to include planner header files here, since most of an index
19  * AM's implementation isn't concerned with those data structures.  To allow
20  * declaring amcostestimate_function here, use forward struct references.
21  */
22 struct PlannerInfo;
23 struct IndexPath;
24 
25 /* Likewise, this file shouldn't depend on execnodes.h. */
26 struct IndexInfo;
27 
28 
29 /*
30  * Properties for amproperty API.  This list covers properties known to the
31  * core code, but an index AM can define its own properties, by matching the
32  * string property name.
33  */
34 typedef enum IndexAMProperty
35 {
36 	AMPROP_UNKNOWN = 0,			/* anything not known to core code */
37 	AMPROP_ASC,					/* column properties */
38 	AMPROP_DESC,
39 	AMPROP_NULLS_FIRST,
40 	AMPROP_NULLS_LAST,
41 	AMPROP_ORDERABLE,
42 	AMPROP_DISTANCE_ORDERABLE,
43 	AMPROP_RETURNABLE,
44 	AMPROP_SEARCH_ARRAY,
45 	AMPROP_SEARCH_NULLS,
46 	AMPROP_CLUSTERABLE,			/* index properties */
47 	AMPROP_INDEX_SCAN,
48 	AMPROP_BITMAP_SCAN,
49 	AMPROP_BACKWARD_SCAN,
50 	AMPROP_CAN_ORDER,			/* AM properties */
51 	AMPROP_CAN_UNIQUE,
52 	AMPROP_CAN_MULTI_COL,
53 	AMPROP_CAN_EXCLUDE,
54 	AMPROP_CAN_INCLUDE
55 } IndexAMProperty;
56 
57 
58 /*
59  * Callback function signatures --- see indexam.sgml for more info.
60  */
61 
62 /* build new index */
63 typedef IndexBuildResult *(*ambuild_function) (Relation heapRelation,
64 											   Relation indexRelation,
65 											   struct IndexInfo *indexInfo);
66 
67 /* build empty index */
68 typedef void (*ambuildempty_function) (Relation indexRelation);
69 
70 /* insert this tuple */
71 typedef bool (*aminsert_function) (Relation indexRelation,
72 								   Datum *values,
73 								   bool *isnull,
74 								   ItemPointer heap_tid,
75 								   Relation heapRelation,
76 								   IndexUniqueCheck checkUnique,
77 								   struct IndexInfo *indexInfo);
78 
79 /* bulk delete */
80 typedef IndexBulkDeleteResult *(*ambulkdelete_function) (IndexVacuumInfo *info,
81 														 IndexBulkDeleteResult *stats,
82 														 IndexBulkDeleteCallback callback,
83 														 void *callback_state);
84 
85 /* post-VACUUM cleanup */
86 typedef IndexBulkDeleteResult *(*amvacuumcleanup_function) (IndexVacuumInfo *info,
87 															IndexBulkDeleteResult *stats);
88 
89 /* can indexscan return IndexTuples? */
90 typedef bool (*amcanreturn_function) (Relation indexRelation, int attno);
91 
92 /* estimate cost of an indexscan */
93 typedef void (*amcostestimate_function) (struct PlannerInfo *root,
94 										 struct IndexPath *path,
95 										 double loop_count,
96 										 Cost *indexStartupCost,
97 										 Cost *indexTotalCost,
98 										 Selectivity *indexSelectivity,
99 										 double *indexCorrelation,
100 										 double *indexPages);
101 
102 /* parse index reloptions */
103 typedef bytea *(*amoptions_function) (Datum reloptions,
104 									  bool validate);
105 
106 /* report AM, index, or index column property */
107 typedef bool (*amproperty_function) (Oid index_oid, int attno,
108 									 IndexAMProperty prop, const char *propname,
109 									 bool *res, bool *isnull);
110 
111 /* validate definition of an opclass for this AM */
112 typedef bool (*amvalidate_function) (Oid opclassoid);
113 
114 /* prepare for index scan */
115 typedef IndexScanDesc (*ambeginscan_function) (Relation indexRelation,
116 											   int nkeys,
117 											   int norderbys);
118 
119 /* (re)start index scan */
120 typedef void (*amrescan_function) (IndexScanDesc scan,
121 								   ScanKey keys,
122 								   int nkeys,
123 								   ScanKey orderbys,
124 								   int norderbys);
125 
126 /* next valid tuple */
127 typedef bool (*amgettuple_function) (IndexScanDesc scan,
128 									 ScanDirection direction);
129 
130 /* fetch all valid tuples */
131 typedef int64 (*amgetbitmap_function) (IndexScanDesc scan,
132 									   TIDBitmap *tbm);
133 
134 /* end index scan */
135 typedef void (*amendscan_function) (IndexScanDesc scan);
136 
137 /* mark current scan position */
138 typedef void (*ammarkpos_function) (IndexScanDesc scan);
139 
140 /* restore marked scan position */
141 typedef void (*amrestrpos_function) (IndexScanDesc scan);
142 
143 /*
144  * Callback function signatures - for parallel index scans.
145  */
146 
147 /* estimate size of parallel scan descriptor */
148 typedef Size (*amestimateparallelscan_function) (void);
149 
150 /* prepare for parallel index scan */
151 typedef void (*aminitparallelscan_function) (void *target);
152 
153 /* (re)start parallel index scan */
154 typedef void (*amparallelrescan_function) (IndexScanDesc scan);
155 
156 /*
157  * API struct for an index AM.  Note this must be stored in a single palloc'd
158  * chunk of memory.
159  */
160 typedef struct IndexAmRoutine
161 {
162 	NodeTag		type;
163 
164 	/*
165 	 * Total number of strategies (operators) by which we can traverse/search
166 	 * this AM.  Zero if AM does not have a fixed set of strategy assignments.
167 	 */
168 	uint16		amstrategies;
169 	/* total number of support functions that this AM uses */
170 	uint16		amsupport;
171 	/* does AM support ORDER BY indexed column's value? */
172 	bool		amcanorder;
173 	/* does AM support ORDER BY result of an operator on indexed column? */
174 	bool		amcanorderbyop;
175 	/* does AM support backward scanning? */
176 	bool		amcanbackward;
177 	/* does AM support UNIQUE indexes? */
178 	bool		amcanunique;
179 	/* does AM support multi-column indexes? */
180 	bool		amcanmulticol;
181 	/* does AM require scans to have a constraint on the first index column? */
182 	bool		amoptionalkey;
183 	/* does AM handle ScalarArrayOpExpr quals? */
184 	bool		amsearcharray;
185 	/* does AM handle IS NULL/IS NOT NULL quals? */
186 	bool		amsearchnulls;
187 	/* can index storage data type differ from column data type? */
188 	bool		amstorage;
189 	/* can an index of this type be clustered on? */
190 	bool		amclusterable;
191 	/* does AM handle predicate locks? */
192 	bool		ampredlocks;
193 	/* does AM support parallel scan? */
194 	bool		amcanparallel;
195 	/* does AM support columns included with clause INCLUDE? */
196 	bool		amcaninclude;
197 	/* type of data stored in index, or InvalidOid if variable */
198 	Oid			amkeytype;
199 
200 	/*
201 	 * If you add new properties to either the above or the below lists, then
202 	 * they should also (usually) be exposed via the property API (see
203 	 * IndexAMProperty at the top of the file, and utils/adt/amutils.c).
204 	 */
205 
206 	/* interface functions */
207 	ambuild_function ambuild;
208 	ambuildempty_function ambuildempty;
209 	aminsert_function aminsert;
210 	ambulkdelete_function ambulkdelete;
211 	amvacuumcleanup_function amvacuumcleanup;
212 	amcanreturn_function amcanreturn;	/* can be NULL */
213 	amcostestimate_function amcostestimate;
214 	amoptions_function amoptions;
215 	amproperty_function amproperty; /* can be NULL */
216 	amvalidate_function amvalidate;
217 	ambeginscan_function ambeginscan;
218 	amrescan_function amrescan;
219 	amgettuple_function amgettuple; /* can be NULL */
220 	amgetbitmap_function amgetbitmap;	/* can be NULL */
221 	amendscan_function amendscan;
222 	ammarkpos_function ammarkpos;	/* can be NULL */
223 	amrestrpos_function amrestrpos; /* can be NULL */
224 
225 	/* interface functions to support parallel index scans */
226 	amestimateparallelscan_function amestimateparallelscan; /* can be NULL */
227 	aminitparallelscan_function aminitparallelscan; /* can be NULL */
228 	amparallelrescan_function amparallelrescan; /* can be NULL */
229 } IndexAmRoutine;
230 
231 
232 /* Functions in access/index/amapi.c */
233 extern IndexAmRoutine *GetIndexAmRoutine(Oid amhandler);
234 extern IndexAmRoutine *GetIndexAmRoutineByAmId(Oid amoid, bool noerror);
235 
236 #endif							/* AMAPI_H */
237