1 /*-------------------------------------------------------------------------
2  *
3  * amapi.h
4  *	  API for Postgres index access methods.
5  *
6  * Copyright (c) 2015-2017, 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 } IndexAMProperty;
55 
56 
57 /*
58  * Callback function signatures --- see indexam.sgml for more info.
59  */
60 
61 /* build new index */
62 typedef IndexBuildResult *(*ambuild_function) (Relation heapRelation,
63 											   Relation indexRelation,
64 											   struct IndexInfo *indexInfo);
65 
66 /* build empty index */
67 typedef void (*ambuildempty_function) (Relation indexRelation);
68 
69 /* insert this tuple */
70 typedef bool (*aminsert_function) (Relation indexRelation,
71 								   Datum *values,
72 								   bool *isnull,
73 								   ItemPointer heap_tid,
74 								   Relation heapRelation,
75 								   IndexUniqueCheck checkUnique,
76 								   struct IndexInfo *indexInfo);
77 
78 /* bulk delete */
79 typedef IndexBulkDeleteResult *(*ambulkdelete_function) (IndexVacuumInfo *info,
80 														 IndexBulkDeleteResult *stats,
81 														 IndexBulkDeleteCallback callback,
82 														 void *callback_state);
83 
84 /* post-VACUUM cleanup */
85 typedef IndexBulkDeleteResult *(*amvacuumcleanup_function) (IndexVacuumInfo *info,
86 															IndexBulkDeleteResult *stats);
87 
88 /* can indexscan return IndexTuples? */
89 typedef bool (*amcanreturn_function) (Relation indexRelation, int attno);
90 
91 /* estimate cost of an indexscan */
92 typedef void (*amcostestimate_function) (struct PlannerInfo *root,
93 										 struct IndexPath *path,
94 										 double loop_count,
95 										 Cost *indexStartupCost,
96 										 Cost *indexTotalCost,
97 										 Selectivity *indexSelectivity,
98 										 double *indexCorrelation,
99 										 double *indexPages);
100 
101 /* parse index reloptions */
102 typedef bytea *(*amoptions_function) (Datum reloptions,
103 									  bool validate);
104 
105 /* report AM, index, or index column property */
106 typedef bool (*amproperty_function) (Oid index_oid, int attno,
107 									 IndexAMProperty prop, const char *propname,
108 									 bool *res, bool *isnull);
109 
110 /* validate definition of an opclass for this AM */
111 typedef bool (*amvalidate_function) (Oid opclassoid);
112 
113 /* prepare for index scan */
114 typedef IndexScanDesc (*ambeginscan_function) (Relation indexRelation,
115 											   int nkeys,
116 											   int norderbys);
117 
118 /* (re)start index scan */
119 typedef void (*amrescan_function) (IndexScanDesc scan,
120 								   ScanKey keys,
121 								   int nkeys,
122 								   ScanKey orderbys,
123 								   int norderbys);
124 
125 /* next valid tuple */
126 typedef bool (*amgettuple_function) (IndexScanDesc scan,
127 									 ScanDirection direction);
128 
129 /* fetch all valid tuples */
130 typedef int64 (*amgetbitmap_function) (IndexScanDesc scan,
131 									   TIDBitmap *tbm);
132 
133 /* end index scan */
134 typedef void (*amendscan_function) (IndexScanDesc scan);
135 
136 /* mark current scan position */
137 typedef void (*ammarkpos_function) (IndexScanDesc scan);
138 
139 /* restore marked scan position */
140 typedef void (*amrestrpos_function) (IndexScanDesc scan);
141 
142 /*
143  * Callback function signatures - for parallel index scans.
144  */
145 
146 /* estimate size of parallel scan descriptor */
147 typedef Size (*amestimateparallelscan_function) (void);
148 
149 /* prepare for parallel index scan */
150 typedef void (*aminitparallelscan_function) (void *target);
151 
152 /* (re)start parallel index scan */
153 typedef void (*amparallelrescan_function) (IndexScanDesc scan);
154 
155 /*
156  * API struct for an index AM.  Note this must be stored in a single palloc'd
157  * chunk of memory.
158  */
159 typedef struct IndexAmRoutine
160 {
161 	NodeTag		type;
162 
163 	/*
164 	 * Total number of strategies (operators) by which we can traverse/search
165 	 * this AM.  Zero if AM does not have a fixed set of strategy assignments.
166 	 */
167 	uint16		amstrategies;
168 	/* total number of support functions that this AM uses */
169 	uint16		amsupport;
170 	/* does AM support ORDER BY indexed column's value? */
171 	bool		amcanorder;
172 	/* does AM support ORDER BY result of an operator on indexed column? */
173 	bool		amcanorderbyop;
174 	/* does AM support backward scanning? */
175 	bool		amcanbackward;
176 	/* does AM support UNIQUE indexes? */
177 	bool		amcanunique;
178 	/* does AM support multi-column indexes? */
179 	bool		amcanmulticol;
180 	/* does AM require scans to have a constraint on the first index column? */
181 	bool		amoptionalkey;
182 	/* does AM handle ScalarArrayOpExpr quals? */
183 	bool		amsearcharray;
184 	/* does AM handle IS NULL/IS NOT NULL quals? */
185 	bool		amsearchnulls;
186 	/* can index storage data type differ from column data type? */
187 	bool		amstorage;
188 	/* can an index of this type be clustered on? */
189 	bool		amclusterable;
190 	/* does AM handle predicate locks? */
191 	bool		ampredlocks;
192 	/* does AM support parallel scan? */
193 	bool		amcanparallel;
194 	/* type of data stored in index, or InvalidOid if variable */
195 	Oid			amkeytype;
196 
197 	/* interface functions */
198 	ambuild_function ambuild;
199 	ambuildempty_function ambuildempty;
200 	aminsert_function aminsert;
201 	ambulkdelete_function ambulkdelete;
202 	amvacuumcleanup_function amvacuumcleanup;
203 	amcanreturn_function amcanreturn;	/* can be NULL */
204 	amcostestimate_function amcostestimate;
205 	amoptions_function amoptions;
206 	amproperty_function amproperty; /* can be NULL */
207 	amvalidate_function amvalidate;
208 	ambeginscan_function ambeginscan;
209 	amrescan_function amrescan;
210 	amgettuple_function amgettuple; /* can be NULL */
211 	amgetbitmap_function amgetbitmap;	/* can be NULL */
212 	amendscan_function amendscan;
213 	ammarkpos_function ammarkpos;	/* can be NULL */
214 	amrestrpos_function amrestrpos; /* can be NULL */
215 
216 	/* interface functions to support parallel index scans */
217 	amestimateparallelscan_function amestimateparallelscan; /* can be NULL */
218 	aminitparallelscan_function aminitparallelscan; /* can be NULL */
219 	amparallelrescan_function amparallelrescan; /* can be NULL */
220 } IndexAmRoutine;
221 
222 
223 /* Functions in access/index/amapi.c */
224 extern IndexAmRoutine *GetIndexAmRoutine(Oid amhandler);
225 extern IndexAmRoutine *GetIndexAmRoutineByAmId(Oid amoid, bool noerror);
226 
227 #endif							/* AMAPI_H */
228