|
- <?xml version="1.0" encoding="UTF-8" standalone="no"?>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>61.2. Index Access Method Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets V1.79.1" /><link rel="prev" href="index-api.html" title="61.1. Basic API Structure for Indexes" /><link rel="next" href="index-scanning.html" title="61.3. Index Scanning" /></head><body><div xmlns="http://www.w3.org/TR/xhtml1/transitional" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">61.2. Index Access Method Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="index-api.html" title="61.1. Basic API Structure for Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexam.html" title="Chapter 61. Index Access Method Interface Definition">Up</a></td><th width="60%" align="center">Chapter 61. Index Access Method Interface Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 12.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="index-scanning.html" title="61.3. Index Scanning">Next</a></td></tr></table><hr></hr></div><div class="sect1" id="INDEX-FUNCTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">61.2. Index Access Method Functions</h2></div></div></div><p>
- The index construction and maintenance functions that an index access
- method must provide in <code class="structname">IndexAmRoutine</code> are:
- </p><p>
- </p><pre class="programlisting">
- IndexBuildResult *
- ambuild (Relation heapRelation,
- Relation indexRelation,
- IndexInfo *indexInfo);
- </pre><p>
- Build a new index. The index relation has been physically created,
- but is empty. It must be filled in with whatever fixed data the
- access method requires, plus entries for all tuples already existing
- in the table. Ordinarily the <code class="function">ambuild</code> function will call
- <code class="function">table_index_build_scan()</code> to scan the table for existing tuples
- and compute the keys that need to be inserted into the index.
- The function must return a palloc'd struct containing statistics about
- the new index.
- </p><p>
- </p><pre class="programlisting">
- void
- ambuildempty (Relation indexRelation);
- </pre><p>
- Build an empty index, and write it to the initialization fork (<code class="symbol">INIT_FORKNUM</code>)
- of the given relation. This method is called only for unlogged indexes; the
- empty index written to the initialization fork will be copied over the main
- relation fork on each server restart.
- </p><p>
- </p><pre class="programlisting">
- bool
- aminsert (Relation indexRelation,
- Datum *values,
- bool *isnull,
- ItemPointer heap_tid,
- Relation heapRelation,
- IndexUniqueCheck checkUnique,
- IndexInfo *indexInfo);
- </pre><p>
- Insert a new tuple into an existing index. The <code class="literal">values</code> and
- <code class="literal">isnull</code> arrays give the key values to be indexed, and
- <code class="literal">heap_tid</code> is the TID to be indexed.
- If the access method supports unique indexes (its
- <code class="structfield">amcanunique</code> flag is true) then
- <code class="literal">checkUnique</code> indicates the type of uniqueness check to
- perform. This varies depending on whether the unique constraint is
- deferrable; see <a class="xref" href="index-unique-checks.html" title="61.5. Index Uniqueness Checks">Section 61.5</a> for details.
- Normally the access method only needs the <code class="literal">heapRelation</code>
- parameter when performing uniqueness checking (since then it will have to
- look into the heap to verify tuple liveness).
- </p><p>
- The function's Boolean result value is significant only when
- <code class="literal">checkUnique</code> is <code class="literal">UNIQUE_CHECK_PARTIAL</code>.
- In this case a true result means the new entry is known unique, whereas
- false means it might be non-unique (and a deferred uniqueness check must
- be scheduled). For other cases a constant false result is recommended.
- </p><p>
- Some indexes might not index all tuples. If the tuple is not to be
- indexed, <code class="function">aminsert</code> should just return without doing anything.
- </p><p>
- If the index AM wishes to cache data across successive index insertions
- within a SQL statement, it can allocate space
- in <code class="literal">indexInfo->ii_Context</code> and store a pointer to the
- data in <code class="literal">indexInfo->ii_AmCache</code> (which will be NULL
- initially).
- </p><p>
- </p><pre class="programlisting">
- IndexBulkDeleteResult *
- ambulkdelete (IndexVacuumInfo *info,
- IndexBulkDeleteResult *stats,
- IndexBulkDeleteCallback callback,
- void *callback_state);
- </pre><p>
- Delete tuple(s) from the index. This is a <span class="quote">“<span class="quote">bulk delete</span>”</span> operation
- that is intended to be implemented by scanning the whole index and checking
- each entry to see if it should be deleted.
- The passed-in <code class="literal">callback</code> function must be called, in the style
- <code class="literal">callback(<em class="replaceable"><code>TID</code></em>, callback_state) returns bool</code>,
- to determine whether any particular index entry, as identified by its
- referenced TID, is to be deleted. Must return either NULL or a palloc'd
- struct containing statistics about the effects of the deletion operation.
- It is OK to return NULL if no information needs to be passed on to
- <code class="function">amvacuumcleanup</code>.
- </p><p>
- Because of limited <code class="varname">maintenance_work_mem</code>,
- <code class="function">ambulkdelete</code> might need to be called more than once when many
- tuples are to be deleted. The <code class="literal">stats</code> argument is the result
- of the previous call for this index (it is NULL for the first call within a
- <code class="command">VACUUM</code> operation). This allows the AM to accumulate statistics
- across the whole operation. Typically, <code class="function">ambulkdelete</code> will
- modify and return the same struct if the passed <code class="literal">stats</code> is not
- null.
- </p><p>
- </p><pre class="programlisting">
- IndexBulkDeleteResult *
- amvacuumcleanup (IndexVacuumInfo *info,
- IndexBulkDeleteResult *stats);
- </pre><p>
- Clean up after a <code class="command">VACUUM</code> operation (zero or more
- <code class="function">ambulkdelete</code> calls). This does not have to do anything
- beyond returning index statistics, but it might perform bulk cleanup
- such as reclaiming empty index pages. <code class="literal">stats</code> is whatever the
- last <code class="function">ambulkdelete</code> call returned, or NULL if
- <code class="function">ambulkdelete</code> was not called because no tuples needed to be
- deleted. If the result is not NULL it must be a palloc'd struct.
- The statistics it contains will be used to update <code class="structname">pg_class</code>,
- and will be reported by <code class="command">VACUUM</code> if <code class="literal">VERBOSE</code> is given.
- It is OK to return NULL if the index was not changed at all during the
- <code class="command">VACUUM</code> operation, but otherwise correct stats should
- be returned.
- </p><p>
- As of <span class="productname">PostgreSQL</span> 8.4,
- <code class="function">amvacuumcleanup</code> will also be called at completion of an
- <code class="command">ANALYZE</code> operation. In this case <code class="literal">stats</code> is always
- NULL and any return value will be ignored. This case can be distinguished
- by checking <code class="literal">info->analyze_only</code>. It is recommended
- that the access method do nothing except post-insert cleanup in such a
- call, and that only in an autovacuum worker process.
- </p><p>
- </p><pre class="programlisting">
- bool
- amcanreturn (Relation indexRelation, int attno);
- </pre><p>
- Check whether the index can support <a class="link" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes"><em class="firstterm">index-only scans</em></a> on
- the given column, by returning the indexed column values for an index entry
- in the form of an <code class="structname">IndexTuple</code>. The attribute number
- is 1-based, i.e. the first column's attno is 1. Returns true if supported,
- else false. If the access method does not support index-only scans at all,
- the <code class="structfield">amcanreturn</code> field in its <code class="structname">IndexAmRoutine</code>
- struct can be set to NULL.
- </p><p>
- </p><pre class="programlisting">
- void
- amcostestimate (PlannerInfo *root,
- IndexPath *path,
- double loop_count,
- Cost *indexStartupCost,
- Cost *indexTotalCost,
- Selectivity *indexSelectivity,
- double *indexCorrelation,
- double *indexPages);
- </pre><p>
- Estimate the costs of an index scan. This function is described fully
- in <a class="xref" href="index-cost-estimation.html" title="61.6. Index Cost Estimation Functions">Section 61.6</a>, below.
- </p><p>
- </p><pre class="programlisting">
- bytea *
- amoptions (ArrayType *reloptions,
- bool validate);
- </pre><p>
- Parse and validate the reloptions array for an index. This is called only
- when a non-null reloptions array exists for the index.
- <em class="parameter"><code>reloptions</code></em> is a <code class="type">text</code> array containing entries of the
- form <em class="replaceable"><code>name</code></em><code class="literal">=</code><em class="replaceable"><code>value</code></em>.
- The function should construct a <code class="type">bytea</code> value, which will be copied
- into the <code class="structfield">rd_options</code> field of the index's relcache entry.
- The data contents of the <code class="type">bytea</code> value are open for the access
- method to define; most of the standard access methods use struct
- <code class="structname">StdRdOptions</code>.
- When <em class="parameter"><code>validate</code></em> is true, the function should report a suitable
- error message if any of the options are unrecognized or have invalid
- values; when <em class="parameter"><code>validate</code></em> is false, invalid entries should be
- silently ignored. (<em class="parameter"><code>validate</code></em> is false when loading options
- already stored in <code class="structname">pg_catalog</code>; an invalid entry could only
- be found if the access method has changed its rules for options, and in
- that case ignoring obsolete entries is appropriate.)
- It is OK to return NULL if default behavior is wanted.
- </p><p>
- </p><pre class="programlisting">
- bool
- amproperty (Oid index_oid, int attno,
- IndexAMProperty prop, const char *propname,
- bool *res, bool *isnull);
- </pre><p>
- The <code class="function">amproperty</code> method allows index access methods to override
- the default behavior of <code class="function">pg_index_column_has_property</code>
- and related functions.
- If the access method does not have any special behavior for index property
- inquiries, the <code class="structfield">amproperty</code> field in
- its <code class="structname">IndexAmRoutine</code> struct can be set to NULL.
- Otherwise, the <code class="function">amproperty</code> method will be called with
- <em class="parameter"><code>index_oid</code></em> and <em class="parameter"><code>attno</code></em> both zero for
- <code class="function">pg_indexam_has_property</code> calls,
- or with <em class="parameter"><code>index_oid</code></em> valid and <em class="parameter"><code>attno</code></em> zero for
- <code class="function">pg_index_has_property</code> calls,
- or with <em class="parameter"><code>index_oid</code></em> valid and <em class="parameter"><code>attno</code></em> greater than
- zero for <code class="function">pg_index_column_has_property</code> calls.
- <em class="parameter"><code>prop</code></em> is an enum value identifying the property being tested,
- while <em class="parameter"><code>propname</code></em> is the original property name string.
- If the core code does not recognize the property name
- then <em class="parameter"><code>prop</code></em> is <code class="literal">AMPROP_UNKNOWN</code>.
- Access methods can define custom property names by
- checking <em class="parameter"><code>propname</code></em> for a match (use <code class="function">pg_strcasecmp</code>
- to match, for consistency with the core code); for names known to the core
- code, it's better to inspect <em class="parameter"><code>prop</code></em>.
- If the <code class="structfield">amproperty</code> method returns <code class="literal">true</code> then
- it has determined the property test result: it must set <code class="literal">*res</code>
- to the boolean value to return, or set <code class="literal">*isnull</code>
- to <code class="literal">true</code> to return a NULL. (Both of the referenced variables
- are initialized to <code class="literal">false</code> before the call.)
- If the <code class="structfield">amproperty</code> method returns <code class="literal">false</code> then
- the core code will proceed with its normal logic for determining the
- property test result.
- </p><p>
- Access methods that support ordering operators should
- implement <code class="literal">AMPROP_DISTANCE_ORDERABLE</code> property testing, as the
- core code does not know how to do that and will return NULL. It may
- also be advantageous to implement <code class="literal">AMPROP_RETURNABLE</code> testing,
- if that can be done more cheaply than by opening the index and calling
- <code class="structfield">amcanreturn</code>, which is the core code's default behavior.
- The default behavior should be satisfactory for all other standard
- properties.
- </p><p>
- </p><pre class="programlisting">
- char *
- ambuildphasename (int64 phasenum);
- </pre><p>
- Return the textual name of the given build phase number.
- The phase numbers are those reported during an index build via the
- <code class="function">pgstat_progress_update_param</code> interface.
- The phase names are then exposed in the
- <code class="structname">pg_stat_progress_create_index</code> view.
- </p><p>
- </p><pre class="programlisting">
- bool
- amvalidate (Oid opclassoid);
- </pre><p>
- Validate the catalog entries for the specified operator class, so far as
- the access method can reasonably do that. For example, this might include
- testing that all required support functions are provided.
- The <code class="function">amvalidate</code> function must return false if the opclass is
- invalid. Problems should be reported with <code class="function">ereport</code> messages.
- </p><p>
- The purpose of an index, of course, is to support scans for tuples matching
- an indexable <code class="literal">WHERE</code> condition, often called a
- <em class="firstterm">qualifier</em> or <em class="firstterm">scan key</em>. The semantics of
- index scanning are described more fully in <a class="xref" href="index-scanning.html" title="61.3. Index Scanning">Section 61.3</a>,
- below. An index access method can support <span class="quote">“<span class="quote">plain</span>”</span> index scans,
- <span class="quote">“<span class="quote">bitmap</span>”</span> index scans, or both. The scan-related functions that an
- index access method must or may provide are:
- </p><p>
- </p><pre class="programlisting">
- IndexScanDesc
- ambeginscan (Relation indexRelation,
- int nkeys,
- int norderbys);
- </pre><p>
- Prepare for an index scan. The <code class="literal">nkeys</code> and <code class="literal">norderbys</code>
- parameters indicate the number of quals and ordering operators that will be
- used in the scan; these may be useful for space allocation purposes.
- Note that the actual values of the scan keys aren't provided yet.
- The result must be a palloc'd struct.
- For implementation reasons the index access method
- <span class="emphasis"><em>must</em></span> create this struct by calling
- <code class="function">RelationGetIndexScan()</code>. In most cases
- <code class="function">ambeginscan</code> does little beyond making that call and perhaps
- acquiring locks;
- the interesting parts of index-scan startup are in <code class="function">amrescan</code>.
- </p><p>
- </p><pre class="programlisting">
- void
- amrescan (IndexScanDesc scan,
- ScanKey keys,
- int nkeys,
- ScanKey orderbys,
- int norderbys);
- </pre><p>
- Start or restart an index scan, possibly with new scan keys. (To restart
- using previously-passed keys, NULL is passed for <code class="literal">keys</code> and/or
- <code class="literal">orderbys</code>.) Note that it is not allowed for
- the number of keys or order-by operators to be larger than
- what was passed to <code class="function">ambeginscan</code>. In practice the restart
- feature is used when a new outer tuple is selected by a nested-loop join
- and so a new key comparison value is needed, but the scan key structure
- remains the same.
- </p><p>
- </p><pre class="programlisting">
- boolean
- amgettuple (IndexScanDesc scan,
- ScanDirection direction);
- </pre><p>
- Fetch the next tuple in the given scan, moving in the given
- direction (forward or backward in the index). Returns true if a tuple was
- obtained, false if no matching tuples remain. In the true case the tuple
- TID is stored into the <code class="literal">scan</code> structure. Note that
- <span class="quote">“<span class="quote">success</span>”</span> means only that the index contains an entry that matches
- the scan keys, not that the tuple necessarily still exists in the heap or
- will pass the caller's snapshot test. On success, <code class="function">amgettuple</code>
- must also set <code class="literal">scan->xs_recheck</code> to true or false.
- False means it is certain that the index entry matches the scan keys.
- true means this is not certain, and the conditions represented by the
- scan keys must be rechecked against the heap tuple after fetching it.
- This provision supports <span class="quote">“<span class="quote">lossy</span>”</span> index operators.
- Note that rechecking will extend only to the scan conditions; a partial
- index predicate (if any) is never rechecked by <code class="function">amgettuple</code>
- callers.
- </p><p>
- If the index supports <a class="link" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes">index-only
- scans</a> (i.e., <code class="function">amcanreturn</code> returns true for it),
- then on success the AM must also check <code class="literal">scan->xs_want_itup</code>,
- and if that is true it must return the originally indexed data for the
- index entry. The data can be returned in the form of an
- <code class="structname">IndexTuple</code> pointer stored at <code class="literal">scan->xs_itup</code>,
- with tuple descriptor <code class="literal">scan->xs_itupdesc</code>; or in the form of
- a <code class="structname">HeapTuple</code> pointer stored at <code class="literal">scan->xs_hitup</code>,
- with tuple descriptor <code class="literal">scan->xs_hitupdesc</code>. (The latter
- format should be used when reconstructing data that might possibly not fit
- into an <code class="structname">IndexTuple</code>.) In either case,
- management of the data referenced by the pointer is the access method's
- responsibility. The data must remain good at least until the next
- <code class="function">amgettuple</code>, <code class="function">amrescan</code>, or <code class="function">amendscan</code>
- call for the scan.
- </p><p>
- The <code class="function">amgettuple</code> function need only be provided if the access
- method supports <span class="quote">“<span class="quote">plain</span>”</span> index scans. If it doesn't, the
- <code class="structfield">amgettuple</code> field in its <code class="structname">IndexAmRoutine</code>
- struct must be set to NULL.
- </p><p>
- </p><pre class="programlisting">
- int64
- amgetbitmap (IndexScanDesc scan,
- TIDBitmap *tbm);
- </pre><p>
- Fetch all tuples in the given scan and add them to the caller-supplied
- <code class="type">TIDBitmap</code> (that is, OR the set of tuple IDs into whatever set is already
- in the bitmap). The number of tuples fetched is returned (this might be
- just an approximate count, for instance some AMs do not detect duplicates).
- While inserting tuple IDs into the bitmap, <code class="function">amgetbitmap</code> can
- indicate that rechecking of the scan conditions is required for specific
- tuple IDs. This is analogous to the <code class="literal">xs_recheck</code> output parameter
- of <code class="function">amgettuple</code>. Note: in the current implementation, support
- for this feature is conflated with support for lossy storage of the bitmap
- itself, and therefore callers recheck both the scan conditions and the
- partial index predicate (if any) for recheckable tuples. That might not
- always be true, however.
- <code class="function">amgetbitmap</code> and
- <code class="function">amgettuple</code> cannot be used in the same index scan; there
- are other restrictions too when using <code class="function">amgetbitmap</code>, as explained
- in <a class="xref" href="index-scanning.html" title="61.3. Index Scanning">Section 61.3</a>.
- </p><p>
- The <code class="function">amgetbitmap</code> function need only be provided if the access
- method supports <span class="quote">“<span class="quote">bitmap</span>”</span> index scans. If it doesn't, the
- <code class="structfield">amgetbitmap</code> field in its <code class="structname">IndexAmRoutine</code>
- struct must be set to NULL.
- </p><p>
- </p><pre class="programlisting">
- void
- amendscan (IndexScanDesc scan);
- </pre><p>
- End a scan and release resources. The <code class="literal">scan</code> struct itself
- should not be freed, but any locks or pins taken internally by the
- access method must be released, as well as any other memory allocated
- by <code class="function">ambeginscan</code> and other scan-related functions.
- </p><p>
- </p><pre class="programlisting">
- void
- ammarkpos (IndexScanDesc scan);
- </pre><p>
- Mark current scan position. The access method need only support one
- remembered scan position per scan.
- </p><p>
- The <code class="function">ammarkpos</code> function need only be provided if the access
- method supports ordered scans. If it doesn't,
- the <code class="structfield">ammarkpos</code> field in its <code class="structname">IndexAmRoutine</code>
- struct may be set to NULL.
- </p><p>
- </p><pre class="programlisting">
- void
- amrestrpos (IndexScanDesc scan);
- </pre><p>
- Restore the scan to the most recently marked position.
- </p><p>
- The <code class="function">amrestrpos</code> function need only be provided if the access
- method supports ordered scans. If it doesn't,
- the <code class="structfield">amrestrpos</code> field in its <code class="structname">IndexAmRoutine</code>
- struct may be set to NULL.
- </p><p>
- In addition to supporting ordinary index scans, some types of index
- may wish to support <em class="firstterm">parallel index scans</em>, which allow
- multiple backends to cooperate in performing an index scan. The
- index access method should arrange things so that each cooperating
- process returns a subset of the tuples that would be performed by
- an ordinary, non-parallel index scan, but in such a way that the
- union of those subsets is equal to the set of tuples that would be
- returned by an ordinary, non-parallel index scan. Furthermore, while
- there need not be any global ordering of tuples returned by a parallel
- scan, the ordering of that subset of tuples returned within each
- cooperating backend must match the requested ordering. The following
- functions may be implemented to support parallel index scans:
- </p><p>
- </p><pre class="programlisting">
- Size
- amestimateparallelscan (void);
- </pre><p>
- Estimate and return the number of bytes of dynamic shared memory which
- the access method will be needed to perform a parallel scan. (This number
- is in addition to, not in lieu of, the amount of space needed for
- AM-independent data in <code class="structname">ParallelIndexScanDescData</code>.)
- </p><p>
- It is not necessary to implement this function for access methods which
- do not support parallel scans or for which the number of additional bytes
- of storage required is zero.
- </p><p>
- </p><pre class="programlisting">
- void
- aminitparallelscan (void *target);
- </pre><p>
- This function will be called to initialize dynamic shared memory at the
- beginning of a parallel scan. <em class="parameter"><code>target</code></em> will point to at least
- the number of bytes previously returned by
- <code class="function">amestimateparallelscan</code>, and this function may use that
- amount of space to store whatever data it wishes.
- </p><p>
- It is not necessary to implement this function for access methods which
- do not support parallel scans or in cases where the shared memory space
- required needs no initialization.
- </p><p>
- </p><pre class="programlisting">
- void
- amparallelrescan (IndexScanDesc scan);
- </pre><p>
- This function, if implemented, will be called when a parallel index scan
- must be restarted. It should reset any shared state set up by
- <code class="function">aminitparallelscan</code> such that the scan will be restarted from
- the beginning.
- </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="index-api.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexam.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="index-scanning.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">61.1. Basic API Structure for Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 61.3. Index Scanning</td></tr></table></div></body></html>
|