In an index scan, the index access method is responsible for regurgitating the TIDs of all the tuples it has been told about that match the scan keys. The access method is not involved in actually fetching those tuples from the index's parent table, nor in determining whether they pass the scan's time qualification test or other conditions.
A scan key is the internal representation of a
WHERE clause of the form
constant, where the index key is
one of the columns of the index and the operator is one of the
members of the operator family associated with that index column.
An index scan has zero or more scan keys, which are implicitly
ANDed — the returned tuples are expected to satisfy all the
The access method can report that the index is lossy, or requires rechecks, for a particular query. This implies that the index scan will return all the entries that pass the scan key, plus possibly additional entries that do not. The core system's index-scan machinery will then apply the index conditions again to the heap tuple to verify whether or not it really should be selected. If the recheck option is not specified, the index scan must return exactly the set of matching entries.
Note that it is entirely up to the access method to ensure that
it correctly finds all and only the entries passing all the given
scan keys. Also, the core system will simply hand off all the
WHERE clauses that match the index
keys and operator families, without any semantic analysis to
determine whether they are redundant or contradictory. As an
WHERE x > 4 AND x >
x is a b-tree indexed
column, it is left to the b-tree
amrescan function to realize that the first scan
key is redundant and can be discarded. The extent of preprocessing
amrescan will depend on
the extent to which the index access method needs to reduce the
scan keys to a “normalized” form.
Some access methods return index entries in a well-defined order, others do not. There are actually two different ways that an access method can support sorted output:
Access methods that always return entries in the natural
ordering of their data (such as btree) should set
amcanorder to true. Currently, such access
methods must use btree-compatible strategy numbers for their
equality and ordering operators.
Access methods that support ordering operators should set
amcanorderbyop to true. This
indicates that the index is capable of returning entries in an
constant. Scan modifiers of that
form can be passed to
amgettuple function has a
direction argument, which can be
normal case) or
If the first call after
the set of matching index entries is to be scanned back-to-front
rather than in the normal front-to-back direction, so
amgettuple must return the last matching tuple in
the index, rather than the first one as it normally would. (This
will only occur for access methods that set
amcanorder to true.) After the first call,
amgettuple must be prepared to
advance the scan in either direction from the most recently
returned entry. (But if
amcanbackward is false, all subsequent calls
will have the same direction as the first one.)
Access methods that support ordered scans must support
position in a scan and later returning to the marked position. The
same position might be restored multiple times. However, only one
position need be remembered per scan; a new
ammarkpos call overrides the previously marked
position. An access method that does not support ordered scans need
amrestrpos functions in
IndexAmRoutine; set those pointers to NULL
Both the scan position and the mark position (if any) must be maintained consistently in the face of concurrent insertions or deletions in the index. It is OK if a freshly-inserted entry is not returned by a scan that would have found the entry if it had existed when the scan started, or for the scan to return such an entry upon rescanning or backing up even though it had not been returned the first time through. Similarly, a concurrent delete might or might not be reflected in the results of a scan. What is important is that insertions or deletions not cause the scan to miss or multiply return entries that were not themselves being inserted or deleted.
If the index stores the original indexed data values (and not some lossy representation of them), it is useful to support index-only scans, in which the index returns the actual data not just the TID of the heap tuple. This will only avoid I/O if the visibility map shows that the TID is on an all-visible page; else the heap tuple must be visited anyway to check MVCC visibility. But that is no concern of the access method's.
Instead of using
index scan can be done with
amgetbitmap to fetch all tuples in one call. This
can be noticeably more efficient than
amgettuple because it allows avoiding lock/unlock
cycles within the access method. In principle
amgetbitmap should have the same effects as
amgettuple calls, but we
impose several restrictions to simplify matters. First of all,
amgetbitmap returns all tuples at
once and marking or restoring scan positions isn't supported.
Secondly, the tuples are returned in a bitmap which doesn't have
any specific ordering, which is why
amgetbitmap doesn't take a
direction argument. (Ordering operators will never
be supplied for such a scan, either.) Also, there is no provision
for index-only scans with
amgetbitmap, since there is no way to return the
contents of index tuples. Finally,
amgetbitmap does not guarantee any locking of the
returned tuples, with implications spelled out in Section 60.4.
Note that it is permitted for an access method to implement only
amgetbitmap and not
amgettuple, or vice versa, if its internal
implementation is unsuited to one API or the other.
If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.