Skip to content

Commit

Permalink
Restructure index access method API to hide most of it at the C level.
Browse files Browse the repository at this point in the history
This patch reduces pg_am to just two columns, a name and a handler
function.  All the data formerly obtained from pg_am is now provided
in a C struct returned by the handler function.  This is similar to
the designs we've adopted for FDWs and tablesample methods.  There
are multiple advantages.  For one, the index AM's support functions
are now simple C functions, making them faster to call and much less
error-prone, since the C compiler can now check function signatures.
For another, this will make it far more practical to define index access
methods in installable extensions.

A disadvantage is that SQL-level code can no longer see attributes
of index AMs; in particular, some of the crosschecks in the opr_sanity
regression test are no longer possible from SQL.  We've addressed that
by adding a facility for the index AM to perform such checks instead.
(Much more could be done in that line, but for now we're content if the
amvalidate functions more or less replace what opr_sanity used to do.)
We might also want to expose some sort of reporting functionality, but
this patch doesn't do that.

Alexander Korotkov, reviewed by Petr Jelínek, and rather heavily
editorialized on by me.
  • Loading branch information
tglsfdc committed Jan 18, 2016
1 parent 8d290c8 commit 65c5fcd
Show file tree
Hide file tree
Showing 93 changed files with 2,494 additions and 1,925 deletions.
1 change: 1 addition & 0 deletions contrib/pageinspect/btreefuncs.c
Expand Up @@ -29,6 +29,7 @@

#include "access/nbtree.h"
#include "catalog/namespace.h"
#include "catalog/pg_am.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "utils/builtins.h"
Expand Down
1 change: 1 addition & 0 deletions contrib/pgstattuple/pgstatindex.c
Expand Up @@ -32,6 +32,7 @@
#include "access/htup_details.h"
#include "access/nbtree.h"
#include "catalog/namespace.h"
#include "catalog/pg_am.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "storage/bufmgr.h"
Expand Down
1 change: 1 addition & 0 deletions contrib/pgstattuple/pgstattuple.c
Expand Up @@ -29,6 +29,7 @@
#include "access/nbtree.h"
#include "access/relscan.h"
#include "catalog/namespace.h"
#include "catalog/pg_am.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "storage/bufmgr.h"
Expand Down
213 changes: 7 additions & 206 deletions doc/src/sgml/catalogs.sgml
Expand Up @@ -516,8 +516,8 @@
<para>
The catalog <structname>pg_am</structname> stores information about index
access methods. There is one row for each index access method supported by
the system. The contents of this catalog are discussed in detail in
<xref linkend="indexam">.
the system. The requirements for index access methods are discussed in
detail in <xref linkend="indexam">.
</para>

<table>
Expand Down Expand Up @@ -549,212 +549,13 @@
</row>

<row>
<entry><structfield>amstrategies</structfield></entry>
<entry><type>int2</type></entry>
<entry></entry>
<entry>Number of operator strategies for this access method,
or zero if access method does not have a fixed set of operator
strategies</entry>
</row>

<row>
<entry><structfield>amsupport</structfield></entry>
<entry><type>int2</type></entry>
<entry></entry>
<entry>Number of support routines for this access method</entry>
</row>

<row>
<entry><structfield>amcanorder</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>Does the access method support ordered scans sorted by the
indexed column's value?</entry>
</row>

<row>
<entry><structfield>amcanorderbyop</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>Does the access method support ordered scans sorted by the result
of an operator on the indexed column?</entry>
</row>

<row>
<entry><structfield>amcanbackward</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>Does the access method support backward scanning?</entry>
</row>

<row>
<entry><structfield>amcanunique</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>Does the access method support unique indexes?</entry>
</row>

<row>
<entry><structfield>amcanmulticol</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>Does the access method support multicolumn indexes?</entry>
</row>

<row>
<entry><structfield>amoptionalkey</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>Does the access method support a scan without any constraint
for the first index column?</entry>
</row>

<row>
<entry><structfield>amsearcharray</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>Does the access method support <literal>ScalarArrayOpExpr</> searches?</entry>
</row>

<row>
<entry><structfield>amsearchnulls</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>Does the access method support <literal>IS NULL</>/<literal>NOT NULL</> searches?</entry>
</row>

<row>
<entry><structfield>amstorage</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>Can index storage data type differ from column data type?</entry>
</row>

<row>
<entry><structfield>amclusterable</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>Can an index of this type be clustered on?</entry>
</row>

<row>
<entry><structfield>ampredlocks</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>Does an index of this type manage fine-grained predicate locks?</entry>
</row>

<row>
<entry><structfield>amkeytype</structfield></entry>
<entry><structfield>amhandler</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
<entry>Type of data stored in index, or zero if not a fixed type</entry>
</row>

<row>
<entry><structfield>aminsert</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry><quote>Insert this tuple</quote> function</entry>
</row>

<row>
<entry><structfield>ambeginscan</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry><quote>Prepare for index scan</quote> function</entry>
</row>

<row>
<entry><structfield>amgettuple</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry><quote>Next valid tuple</quote> function, or zero if none</entry>
</row>

<row>
<entry><structfield>amgetbitmap</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry><quote>Fetch all valid tuples</quote> function, or zero if none</entry>
</row>

<row>
<entry><structfield>amrescan</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry><quote>(Re)start index scan</quote> function</entry>
</row>

<row>
<entry><structfield>amendscan</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry><quote>Clean up after index scan</quote> function</entry>
</row>

<row>
<entry><structfield>ammarkpos</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry><quote>Mark current scan position</quote> function</entry>
</row>

<row>
<entry><structfield>amrestrpos</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry><quote>Restore marked scan position</quote> function</entry>
</row>

<row>
<entry><structfield>ambuild</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry><quote>Build new index</quote> function</entry>
</row>

<row>
<entry><structfield>ambuildempty</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry><quote>Build empty index</quote> function</entry>
</row>

<row>
<entry><structfield>ambulkdelete</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry>Bulk-delete function</entry>
</row>

<row>
<entry><structfield>amvacuumcleanup</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry>Post-<command>VACUUM</command> cleanup function</entry>
</row>

<row>
<entry><structfield>amcanreturn</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry>Function to check whether an index column supports index-only
scans. Can be zero if index-only scans are never supported.</entry>
</row>

<row>
<entry><structfield>amcostestimate</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry>Function to estimate cost of an index scan</entry>
</row>

<row>
<entry><structfield>amoptions</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry>Function to parse and validate <structfield>reloptions</> for an index</entry>
<entry>
OID of a handler function that is responsible for supplying information
about the access method
</entry>
</row>

</tbody>
Expand Down
9 changes: 9 additions & 0 deletions doc/src/sgml/datatype.sgml
Expand Up @@ -4632,6 +4632,10 @@ SELECT * FROM pg_attribute
<primary>fdw_handler</primary>
</indexterm>

<indexterm zone="datatype-pseudo">
<primary>index_am_handler</primary>
</indexterm>

<indexterm zone="datatype-pseudo">
<primary>tsm_handler</primary>
</indexterm>
Expand Down Expand Up @@ -4730,6 +4734,11 @@ SELECT * FROM pg_attribute
<entry>A foreign-data wrapper handler is declared to return <type>fdw_handler</>.</entry>
</row>

<row>
<entry><type>index_am_handler</></entry>
<entry>An index access method handler is declared to return <type>index_am_handler</>.</entry>
</row>

<row>
<entry><type>tsm_handler</></entry>
<entry>A tablesample method handler is declared to return <type>tsm_handler</>.</entry>
Expand Down

0 comments on commit 65c5fcd

Please sign in to comment.