the
<xref linkend="sql-create-access-method"/> and
<xref linkend="sql-drop-access-method"/> SQL commands.
</para>
<para>
An index access method handler function must be declared to accept a
single argument of type <type>internal</type> and to return the
pseudo-type <type>index_am_handler</type>. The argument is a dummy value that
simply serves to prevent handler functions from being called directly from
SQL commands. The result of the function must be a palloc'd struct of
type <structname>IndexAmRoutine</structname>, which contains everything
that the core code needs to know to make use of the index access method.
The <structname>IndexAmRoutine</structname> struct, also called the access
method's <firstterm>API struct</firstterm>, includes fields specifying assorted
fixed properties of the access method, such as whether it can support
multicolumn indexes. More importantly, it contains pointers to support
functions for the access method, which do all of the real work to access
indexes. These support functions are plain C functions and are not
visible or callable at the SQL level. The support functions are described
in <xref linkend="index-functions"/>.
</para>
<para>
The structure <structname>IndexAmRoutine</structname> is defined thus:
<programlisting>
typedef struct IndexAmRoutine
{
NodeTag type;
/*
* Total number of strategies (operators) by which we can traverse/search
* this AM. Zero if AM does not have a fixed set of strategy assignments.
*/
uint16 amstrategies;
/* total number of support functions that this AM uses */
uint16 amsupport;
/* opclass options support function number or 0 */
uint16 amoptsprocnum;
/* does AM support ORDER BY indexed column's value? */
bool amcanorder;
/* does AM support ORDER BY result of an operator on indexed column? */
bool amcanorderbyop;
/* does AM support hashing using API consistent with the hash AM? */
bool amcanhash;
/* do operators within an opfamily have consistent equality semantics? */
bool amconsistentequality;
/* do operators within an opfamily have consistent ordering semantics? */
bool amconsistentordering;
/* does AM support backward scanning? */
bool amcanbackward;
/* does AM support UNIQUE indexes? */
bool amcanunique;
/* does AM support multi-column indexes? */
bool amcanmulticol;
/* does AM require scans to have a constraint on the first index column? */
bool amoptionalkey;
/* does AM handle ScalarArrayOpExpr quals? */
bool amsearcharray;
/* does AM handle IS NULL/IS NOT NULL quals? */
bool amsearchnulls;
/* can index storage data type differ from column data type? */
bool amstorage;
/* can an index of this type be clustered on? */
bool amclusterable;
/* does AM handle predicate locks? */
bool ampredlocks;
/* does AM support parallel scan? */
bool amcanparallel;
/* does AM support parallel build? */
bool amcanbuildparallel;
/* does AM support columns included with clause INCLUDE? */
bool amcaninclude;
/* does AM use maintenance_work_mem? */
bool amusemaintenanceworkmem;
/* does AM summarize tuples, with at least all tuples in the block
* summarized in one summary */
bool amsummarizing;
/* OR of parallel vacuum flags */
uint8 amparallelvacuumoptions;
/* type of data stored in index, or InvalidOid if variable */
Oid amkeytype;
/* interface functions */
ambuild_function ambuild;
ambuildempty_function ambuildempty;
aminsert_function aminsert;
aminsertcleanup_function aminsertcleanup;
ambulkdelete_function ambulkdelete;
amvacuumcleanup_function amvacuumcleanup;
amcanreturn_function amcanreturn; /* can