2 63.2. Index Access Method Functions #
4 The index construction and maintenance functions that an index access
5 method must provide in IndexAmRoutine are:
8 ambuild (Relation heapRelation,
9 Relation indexRelation,
10 IndexInfo *indexInfo);
12 Build a new index. The index relation has been physically created, but
13 is empty. It must be filled in with whatever fixed data the access
14 method requires, plus entries for all tuples already existing in the
15 table. Ordinarily the ambuild function will call
16 table_index_build_scan() to scan the table for existing tuples and
17 compute the keys that need to be inserted into the index. The function
18 must return a palloc'd struct containing statistics about the new
19 index. The amcanbuildparallel flag indicates whether the access method
20 supports parallel index builds. When set to true, the system will
21 attempt to allocate parallel workers for the build. Access methods
22 supporting only non-parallel index builds should leave this flag set to
26 ambuildempty (Relation indexRelation);
28 Build an empty index, and write it to the initialization fork
29 (INIT_FORKNUM) of the given relation. This method is called only for
30 unlogged indexes; the empty index written to the initialization fork
31 will be copied over the main relation fork on each server restart.
34 aminsert (Relation indexRelation,
38 Relation heapRelation,
39 IndexUniqueCheck checkUnique,
41 IndexInfo *indexInfo);
43 Insert a new tuple into an existing index. The values and isnull arrays
44 give the key values to be indexed, and heap_tid is the TID to be
45 indexed. If the access method supports unique indexes (its amcanunique
46 flag is true) then checkUnique indicates the type of uniqueness check
47 to perform. This varies depending on whether the unique constraint is
48 deferrable; see Section 63.5 for details. Normally the access method
49 only needs the heapRelation parameter when performing uniqueness
50 checking (since then it will have to look into the heap to verify tuple
53 The indexUnchanged Boolean value gives a hint about the nature of the
54 tuple to be indexed. When it is true, the tuple is a duplicate of some
55 existing tuple in the index. The new tuple is a logically unchanged
56 successor MVCC tuple version. This happens when an UPDATE takes place
57 that does not modify any columns covered by the index, but nevertheless
58 requires a new version in the index. The index AM may use this hint to
59 decide to apply bottom-up index deletion in parts of the index where
60 many versions of the same logical row accumulate. Note that updating a
61 non-key column or a column that only appears in a partial index
62 predicate does not affect the value of indexUnchanged. The core code
63 determines each tuple's indexUnchanged value using a low overhead
64 approach that allows both false positives and false negatives. Index
65 AMs must not treat indexUnchanged as an authoritative source of
66 information about tuple visibility or versioning.
68 The function's Boolean result value is significant only when
69 checkUnique is UNIQUE_CHECK_PARTIAL. In this case a true result means
70 the new entry is known unique, whereas false means it might be
71 non-unique (and a deferred uniqueness check must be scheduled). For
72 other cases a constant false result is recommended.
74 Some indexes might not index all tuples. If the tuple is not to be
75 indexed, aminsert should just return without doing anything.
77 If the index AM wishes to cache data across successive index insertions
78 within an SQL statement, it can allocate space in indexInfo->ii_Context
79 and store a pointer to the data in indexInfo->ii_AmCache (which will be
80 NULL initially). If resources other than memory have to be released
81 after index insertions, aminsertcleanup may be provided, which will be
82 called before the memory is released.
85 aminsertcleanup (Relation indexRelation,
86 IndexInfo *indexInfo);
88 Clean up state that was maintained across successive inserts in
89 indexInfo->ii_AmCache. This is useful if the data requires additional
90 cleanup steps (e.g., releasing pinned buffers), and simply releasing
91 the memory is not sufficient.
93 IndexBulkDeleteResult *
94 ambulkdelete (IndexVacuumInfo *info,
95 IndexBulkDeleteResult *stats,
96 IndexBulkDeleteCallback callback,
97 void *callback_state);
99 Delete tuple(s) from the index. This is a “bulk delete” operation that
100 is intended to be implemented by scanning the whole index and checking
101 each entry to see if it should be deleted. The passed-in callback
102 function must be called, in the style callback(TID, callback_state)
103 returns bool, to determine whether any particular index entry, as
104 identified by its referenced TID, is to be deleted. Must return either
105 NULL or a palloc'd struct containing statistics about the effects of
106 the deletion operation. It is OK to return NULL if no information needs
107 to be passed on to amvacuumcleanup.
109 Because of limited maintenance_work_mem, ambulkdelete might need to be
110 called more than once when many tuples are to be deleted. The stats
111 argument is the result of the previous call for this index (it is NULL
112 for the first call within a VACUUM operation). This allows the AM to
113 accumulate statistics across the whole operation. Typically,
114 ambulkdelete will modify and return the same struct if the passed stats
117 IndexBulkDeleteResult *
118 amvacuumcleanup (IndexVacuumInfo *info,
119 IndexBulkDeleteResult *stats);
121 Clean up after a VACUUM operation (zero or more ambulkdelete calls).
122 This does not have to do anything beyond returning index statistics,
123 but it might perform bulk cleanup such as reclaiming empty index pages.
124 stats is whatever the last ambulkdelete call returned, or NULL if
125 ambulkdelete was not called because no tuples needed to be deleted. If
126 the result is not NULL it must be a palloc'd struct. The statistics it
127 contains will be used to update pg_class, and will be reported by
128 VACUUM if VERBOSE is given. It is OK to return NULL if the index was
129 not changed at all during the VACUUM operation, but otherwise correct
130 stats should be returned.
132 amvacuumcleanup will also be called at completion of an ANALYZE
133 operation. In this case stats is always NULL and any return value will
134 be ignored. This case can be distinguished by checking
135 info->analyze_only. It is recommended that the access method do nothing
136 except post-insert cleanup in such a call, and that only in an
137 autovacuum worker process.
140 amcanreturn (Relation indexRelation, int attno);
142 Check whether the index can support index-only scans on the given
143 column, by returning the column's original indexed value. The attribute
144 number is 1-based, i.e., the first column's attno is 1. Returns true if
145 supported, else false. This function should always return true for
146 included columns (if those are supported), since there's little point
147 in an included column that can't be retrieved. If the access method
148 does not support index-only scans at all, the amcanreturn field in its
149 IndexAmRoutine struct can be set to NULL.
152 amcostestimate (PlannerInfo *root,
155 Cost *indexStartupCost,
156 Cost *indexTotalCost,
157 Selectivity *indexSelectivity,
158 double *indexCorrelation,
161 Estimate the costs of an index scan. This function is described fully
162 in Section 63.6, below.
165 amgettreeheight (Relation rel);
167 Compute the height of a tree-shaped index. This information is supplied
168 to the amcostestimate function in path->indexinfo->tree_height and can
169 be used to support the cost estimation. The result is not used anywhere
170 else, so this function can actually be used to compute any kind of data
171 (that fits into an integer) about the index that the cost estimation
172 function might want to know. If the computation is expensive, it could
173 be useful to cache the result as part of RelationData.rd_amcache.
176 amoptions (ArrayType *reloptions,
179 Parse and validate the reloptions array for an index. This is called
180 only when a non-null reloptions array exists for the index. reloptions
181 is a text array containing entries of the form name=value. The function
182 should construct a bytea value, which will be copied into the
183 rd_options field of the index's relcache entry. The data contents of
184 the bytea value are open for the access method to define; most of the
185 standard access methods use struct StdRdOptions. When validate is true,
186 the function should report a suitable error message if any of the
187 options are unrecognized or have invalid values; when validate is
188 false, invalid entries should be silently ignored. (validate is false
189 when loading options already stored in pg_catalog; an invalid entry
190 could only be found if the access method has changed its rules for
191 options, and in that case ignoring obsolete entries is appropriate.) It
192 is OK to return NULL if default behavior is wanted.
195 amproperty (Oid index_oid, int attno,
196 IndexAMProperty prop, const char *propname,
197 bool *res, bool *isnull);
199 The amproperty method allows index access methods to override the
200 default behavior of pg_index_column_has_property and related functions.
201 If the access method does not have any special behavior for index
202 property inquiries, the amproperty field in its IndexAmRoutine struct
203 can be set to NULL. Otherwise, the amproperty method will be called
204 with index_oid and attno both zero for pg_indexam_has_property calls,
205 or with index_oid valid and attno zero for pg_index_has_property calls,
206 or with index_oid valid and attno greater than zero for
207 pg_index_column_has_property calls. prop is an enum value identifying
208 the property being tested, while propname is the original property name
209 string. If the core code does not recognize the property name then prop
210 is AMPROP_UNKNOWN. Access methods can define custom property names by
211 checking propname for a match (use pg_strcasecmp to match, for
212 consistency with the core code); for names known to the core code, it's
213 better to inspect prop. If the amproperty method returns true then it
214 has determined the property test result: it must set *res to the
215 Boolean value to return, or set *isnull to true to return a NULL. (Both
216 of the referenced variables are initialized to false before the call.)
217 If the amproperty method returns false then the core code will proceed
218 with its normal logic for determining the property test result.
220 Access methods that support ordering operators should implement
221 AMPROP_DISTANCE_ORDERABLE property testing, as the core code does not
222 know how to do that and will return NULL. It may also be advantageous
223 to implement AMPROP_RETURNABLE testing, if that can be done more
224 cheaply than by opening the index and calling amcanreturn, which is the
225 core code's default behavior. The default behavior should be
226 satisfactory for all other standard properties.
229 ambuildphasename (int64 phasenum);
231 Return the textual name of the given build phase number. The phase
232 numbers are those reported during an index build via the
233 pgstat_progress_update_param interface. The phase names are then
234 exposed in the pg_stat_progress_create_index view.
237 amvalidate (Oid opclassoid);
239 Validate the catalog entries for the specified operator class, so far
240 as the access method can reasonably do that. For example, this might
241 include testing that all required support functions are provided. The
242 amvalidate function must return false if the opclass is invalid.
243 Problems should be reported with ereport messages, typically at INFO
247 amadjustmembers (Oid opfamilyoid,
252 Validate proposed new operator and function members of an operator
253 family, so far as the access method can reasonably do that, and set
254 their dependency types if the default is not satisfactory. This is
255 called during CREATE OPERATOR CLASS and during ALTER OPERATOR FAMILY
256 ADD; in the latter case opclassoid is InvalidOid. The List arguments
257 are lists of OpFamilyMember structs, as defined in amapi.h. Tests done
258 by this function will typically be a subset of those performed by
259 amvalidate, since amadjustmembers cannot assume that it is seeing a
260 complete set of members. For example, it would be reasonable to check
261 the signature of a support function, but not to check whether all
262 required support functions are provided. Any problems can be reported
263 by throwing an error. The dependency-related fields of the
264 OpFamilyMember structs are initialized by the core code to create hard
265 dependencies on the opclass if this is CREATE OPERATOR CLASS, or soft
266 dependencies on the opfamily if this is ALTER OPERATOR FAMILY ADD.
267 amadjustmembers can adjust these fields if some other behavior is more
268 appropriate. For example, GIN, GiST, and SP-GiST always set operator
269 members to have soft dependencies on the opfamily, since the connection
270 between an operator and an opclass is relatively weak in these index
271 types; so it is reasonable to allow operator members to be added and
272 removed freely. Optional support functions are typically also given
273 soft dependencies, so that they can be removed if necessary.
275 The purpose of an index, of course, is to support scans for tuples
276 matching an indexable WHERE condition, often called a qualifier or scan
277 key. The semantics of index scanning are described more fully in
278 Section 63.3, below. An index access method can support “plain” index
279 scans, “bitmap” index scans, or both. The scan-related functions that
280 an index access method must or may provide are:
283 ambeginscan (Relation indexRelation,
287 Prepare for an index scan. The nkeys and norderbys parameters indicate
288 the number of quals and ordering operators that will be used in the
289 scan; these may be useful for space allocation purposes. Note that the
290 actual values of the scan keys aren't provided yet. The result must be
291 a palloc'd struct. For implementation reasons the index access method
292 must create this struct by calling RelationGetIndexScan(). In most
293 cases ambeginscan does little beyond making that call and perhaps
294 acquiring locks; the interesting parts of index-scan startup are in
298 amrescan (IndexScanDesc scan,
304 Start or restart an index scan, possibly with new scan keys. (To
305 restart using previously-passed keys, NULL is passed for keys and/or
306 orderbys.) Note that it is not allowed for the number of keys or
307 order-by operators to be larger than what was passed to ambeginscan. In
308 practice the restart feature is used when a new outer tuple is selected
309 by a nested-loop join and so a new key comparison value is needed, but
310 the scan key structure remains the same.
313 amgettuple (IndexScanDesc scan,
314 ScanDirection direction);
316 Fetch the next tuple in the given scan, moving in the given direction
317 (forward or backward in the index). Returns true if a tuple was
318 obtained, false if no matching tuples remain. In the true case the
319 tuple TID is stored into the scan structure. Note that “success” means
320 only that the index contains an entry that matches the scan keys, not
321 that the tuple necessarily still exists in the heap or will pass the
322 caller's snapshot test. On success, amgettuple must also set
323 scan->xs_recheck to true or false. False means it is certain that the
324 index entry matches the scan keys. True means this is not certain, and
325 the conditions represented by the scan keys must be rechecked against
326 the heap tuple after fetching it. This provision supports “lossy” index
327 operators. Note that rechecking will extend only to the scan
328 conditions; a partial index predicate (if any) is never rechecked by
331 If the index supports index-only scans (i.e., amcanreturn returns true
332 for any of its columns), then on success the AM must also check
333 scan->xs_want_itup, and if that is true it must return the originally
334 indexed data for the index entry. Columns for which amcanreturn returns
335 false can be returned as nulls. The data can be returned in the form of
336 an IndexTuple pointer stored at scan->xs_itup, with tuple descriptor
337 scan->xs_itupdesc; or in the form of a HeapTuple pointer stored at
338 scan->xs_hitup, with tuple descriptor scan->xs_hitupdesc. (The latter
339 format should be used when reconstructing data that might possibly not
340 fit into an IndexTuple.) In either case, management of the data
341 referenced by the pointer is the access method's responsibility. The
342 data must remain good at least until the next amgettuple, amrescan, or
343 amendscan call for the scan.
345 The amgettuple function need only be provided if the access method
346 supports “plain” index scans. If it doesn't, the amgettuple field in
347 its IndexAmRoutine struct must be set to NULL.
350 amgetbitmap (IndexScanDesc scan,
353 Fetch all tuples in the given scan and add them to the caller-supplied
354 TIDBitmap (that is, OR the set of tuple IDs into whatever set is
355 already in the bitmap). The number of tuples fetched is returned (this
356 might be just an approximate count, for instance some AMs do not detect
357 duplicates). While inserting tuple IDs into the bitmap, amgetbitmap can
358 indicate that rechecking of the scan conditions is required for
359 specific tuple IDs. This is analogous to the xs_recheck output
360 parameter of amgettuple. Note: in the current implementation, support
361 for this feature is conflated with support for lossy storage of the
362 bitmap itself, and therefore callers recheck both the scan conditions
363 and the partial index predicate (if any) for recheckable tuples. That
364 might not always be true, however. amgetbitmap and amgettuple cannot be
365 used in the same index scan; there are other restrictions too when
366 using amgetbitmap, as explained in Section 63.3.
368 The amgetbitmap function need only be provided if the access method
369 supports “bitmap” index scans. If it doesn't, the amgetbitmap field in
370 its IndexAmRoutine struct must be set to NULL.
373 amendscan (IndexScanDesc scan);
375 End a scan and release resources. The scan struct itself should not be
376 freed, but any locks or pins taken internally by the access method must
377 be released, as well as any other memory allocated by ambeginscan and
378 other scan-related functions.
381 ammarkpos (IndexScanDesc scan);
383 Mark current scan position. The access method need only support one
384 remembered scan position per scan.
386 The ammarkpos function need only be provided if the access method
387 supports ordered scans. If it doesn't, the ammarkpos field in its
388 IndexAmRoutine struct may be set to NULL.
391 amrestrpos (IndexScanDesc scan);
393 Restore the scan to the most recently marked position.
395 The amrestrpos function need only be provided if the access method
396 supports ordered scans. If it doesn't, the amrestrpos field in its
397 IndexAmRoutine struct may be set to NULL.
399 In addition to supporting ordinary index scans, some types of index may
400 wish to support parallel index scans, which allow multiple backends to
401 cooperate in performing an index scan. The index access method should
402 arrange things so that each cooperating process returns a subset of the
403 tuples that would be performed by an ordinary, non-parallel index scan,
404 but in such a way that the union of those subsets is equal to the set
405 of tuples that would be returned by an ordinary, non-parallel index
406 scan. Furthermore, while there need not be any global ordering of
407 tuples returned by a parallel scan, the ordering of that subset of
408 tuples returned within each cooperating backend must match the
409 requested ordering. The following functions may be implemented to
410 support parallel index scans:
413 amestimateparallelscan (Relation indexRelation,
417 Estimate and return the number of bytes of dynamic shared memory which
418 the access method will be needed to perform a parallel scan. (This
419 number is in addition to, not in lieu of, the amount of space needed
420 for AM-independent data in ParallelIndexScanDescData.)
422 The nkeys and norderbys parameters indicate the number of quals and
423 ordering operators that will be used in the scan; the same values will
424 be passed to amrescan. Note that the actual values of the scan keys
427 It is not necessary to implement this function for access methods which
428 do not support parallel scans or for which the number of additional
429 bytes of storage required is zero.
432 aminitparallelscan (void *target);
434 This function will be called to initialize dynamic shared memory at the
435 beginning of a parallel scan. target will point to at least the number
436 of bytes previously returned by amestimateparallelscan, and this
437 function may use that amount of space to store whatever data it wishes.
439 It is not necessary to implement this function for access methods which
440 do not support parallel scans or in cases where the shared memory space
441 required needs no initialization.
444 amparallelrescan (IndexScanDesc scan);
446 This function, if implemented, will be called when a parallel index
447 scan must be restarted. It should reset any shared state set up by
448 aminitparallelscan such that the scan will be restarted from the
452 amtranslatestrategy (StrategyNumber strategy, Oid opfamily, Oid opcintype);
455 amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype);
457 These functions, if implemented, will be called by the planner and
458 executor to convert between fixed CompareType values and the specific
459 strategy numbers used by the access method. These functions can be
460 implemented by access methods that implement functionality similar to
461 the built-in btree or hash access methods, and by implementing these
462 translations, the system can learn about the semantics of the access
463 method's operations and can use them in place of btree or hash indexes
464 in various places. If the functionality of the access method is not
465 similar to those built-in access methods, these functions do not need
466 to be implemented. If the functions are not implemented, the access
467 method will be ignored for certain planner and executor decisions, but
468 is otherwise fully functional.