be non-unique (and a deferred uniqueness check must
be scheduled). For other cases a constant false result is recommended.
</para>
<para>
Some indexes might not index all tuples. If the tuple is not to be
indexed, <function>aminsert</function> should just return without doing anything.
</para>
<para>
If the index AM wishes to cache data across successive index insertions
within an SQL statement, it can allocate space
in <literal>indexInfo->ii_Context</literal> and store a pointer to the
data in <literal>indexInfo->ii_AmCache</literal> (which will be NULL
initially). If resources other than memory have to be released after
index insertions, <function>aminsertcleanup</function> may be provided,
which will be called before the memory is released.
</para>
<para>
<programlisting>
void
aminsertcleanup (Relation indexRelation,
IndexInfo *indexInfo);
</programlisting>
Clean up state that was maintained across successive inserts in
<literal>indexInfo->ii_AmCache</literal>. This is useful if the data
requires additional cleanup steps (e.g., releasing pinned buffers), and
simply releasing the memory is not sufficient.
</para>
<para>
<programlisting>
IndexBulkDeleteResult *
ambulkdelete (IndexVacuumInfo *info,
IndexBulkDeleteResult *stats,
IndexBulkDeleteCallback callback,
void *callback_state);
</programlisting>
Delete tuple(s) from the index. This is a <quote>bulk delete</quote> 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 <literal>callback</literal> function must be called, in the style
<literal>callback(<replaceable>TID</replaceable>, callback_state) returns bool</literal>,
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
<function>amvacuumcleanup</function>.
</para>
<para>
Because of limited <varname>maintenance_work_mem</varname>,
<function>ambulkdelete</function> might need to be called more than once when many
tuples are to be deleted. The <literal>stats</literal> argument is the result
of the previous call for this index (it is NULL for the first call within a
<command>VACUUM</command> operation). This allows the AM to accumulate statistics
across the whole operation. Typically, <function>ambulkdelete</function> will
modify and return the same struct if the passed <literal>stats</literal> is not
null.
</para>
<para>
<programlisting>
IndexBulkDeleteResult *
amvacuumcleanup (IndexVacuumInfo *info,
IndexBulkDeleteResult *stats);
</programlisting>
Clean up after a <command>VACUUM</command> operation (zero or 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