more
<function>ambulkdelete</function> calls). This does not have to do anything
beyond returning index statistics, but it might perform bulk cleanup
such as reclaiming empty index pages. <literal>stats</literal> is whatever the
last <function>ambulkdelete</function> call returned, or NULL if
<function>ambulkdelete</function> 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 <structname>pg_class</structname>,
and will be reported by <command>VACUUM</command> if <literal>VERBOSE</literal> is given.
It is OK to return NULL if the index was not changed at all during the
<command>VACUUM</command> operation, but otherwise correct stats should
be returned.
</para>
<para>
<function>amvacuumcleanup</function> will also be called at completion of an
<command>ANALYZE</command> operation. In this case <literal>stats</literal> is always
NULL and any return value will be ignored. This case can be distinguished
by checking <literal>info->analyze_only</literal>. 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.
</para>
<para>
<programlisting>
bool
amcanreturn (Relation indexRelation, int attno);
</programlisting>
Check whether the index can support <link
linkend="indexes-index-only-scans"><firstterm>index-only scans</firstterm></link> on
the given column, by returning the column's original indexed value.
The attribute number is 1-based, i.e., the first column's attno is 1.
Returns true if supported, else false.
This function should always return true for included columns
(if those are supported), since there's little point in an included
column that can't be retrieved.
If the access method does not support index-only scans at all,
the <structfield>amcanreturn</structfield> field in its <structname>IndexAmRoutine</structname>
struct can be set to NULL.
</para>
<para>
<programlisting>
void
amcostestimate (PlannerInfo *root,
IndexPath *path,
double loop_count,
Cost *indexStartupCost,
Cost *indexTotalCost,
Selectivity *indexSelectivity,
double *indexCorrelation,
double *indexPages);
</programlisting>
Estimate the costs of an index scan. This function is described fully
in <xref linkend="index-cost-estimation"/>, below.
</para>
<para>
<programlisting>
int
amgettreeheight (Relation rel);
</programlisting>
Compute the height of a tree-shaped index. This information is supplied to
the <function>amcostestimate</function> function in
<literal>path->indexinfo->tree_height</literal> and can be used to support
the cost estimation. The result is not used anywhere else, so this
function can actually be used to compute any kind of data (that fits into
an integer) about the index that the cost estimation function might want to
know. If the computation is expensive, it could be useful to cache the
result as part of <literal>RelationData.rd_amcache</literal>.
</para>
<para>
<programlisting>
bytea *
amoptions (ArrayType *reloptions,
bool validate);
</programlisting>
Parse and validate the reloptions array for an index. This is called only
when a non-null reloptions array exists for the index.
<parameter>reloptions</parameter> is a <type>text</type> array containing entries of the
form <replaceable>name</replaceable><literal>=</literal><replaceable>value</replaceable>.
The function should construct a <type>bytea</type> value, which will be copied
into the <structfield>rd_options</structfield> field of the index's relcache entry.
The data contents of the <type>bytea</type> value are open for the access
method to define; most of the standard access methods use struct