summaryrefslogtreecommitdiff
path: root/doc/src
diff options
context:
space:
mode:
authorHeikki Linnakangas2015-03-26 17:12:00 +0000
committerHeikki Linnakangas2015-03-26 17:12:00 +0000
commitd04c8ed9044eccebce043143a930617e3998c005 (patch)
treee0167be995bb28dab91dfb92f1e18609e91a0d3e /doc/src
parent8fa393a6d739796d9f06a7fba91d7e1d0c354879 (diff)
Add support for index-only scans in GiST.
This adds a new GiST opclass method, 'fetch', which is used to reconstruct the original Datum from the value stored in the index. Also, the 'canreturn' index AM interface function gains a new 'attno' argument. That makes it possible to use index-only scans on a multi-column index where some of the opclasses support index-only scans but some do not. This patch adds support in the box and point opclasses. Other opclasses can added later as follow-on patches (btree_gist would be particularly interesting). Anastasia Lubennikova, with additional fixes and modifications by me.
Diffstat (limited to 'doc/src')
-rw-r--r--doc/src/sgml/catalogs.sgml4
-rw-r--r--doc/src/sgml/gist.sgml73
-rw-r--r--doc/src/sgml/indexam.sgml15
3 files changed, 80 insertions, 12 deletions
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index dfed546f513..d0b78f27827 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -724,8 +724,8 @@
<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 index supports index-only scans,
- or zero if none</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>
diff --git a/doc/src/sgml/gist.sgml b/doc/src/sgml/gist.sgml
index 31ce2790047..e7d1ff9d83f 100644
--- a/doc/src/sgml/gist.sgml
+++ b/doc/src/sgml/gist.sgml
@@ -266,7 +266,7 @@ CREATE INDEX ON my_table USING gist (my_inet_column inet_ops);
<para>
There are seven methods that an index operator class for
- <acronym>GiST</acronym> must provide, and an eighth that is optional.
+ <acronym>GiST</acronym> must provide, and two that are optional.
Correctness of the index is ensured
by proper implementation of the <function>same</>, <function>consistent</>
and <function>union</> methods, while efficiency (size and speed) of the
@@ -282,7 +282,8 @@ CREATE INDEX ON my_table USING gist (my_inet_column inet_ops);
of the <command>CREATE OPERATOR CLASS</> command can be used.
The optional eighth method is <function>distance</>, which is needed
if the operator class wishes to support ordered scans (nearest-neighbor
- searches).
+ searches). The optional ninth method <function>fetch</> is needed if the
+ operator class wishes to support index-only scans.
</para>
<variablelist>
@@ -506,7 +507,7 @@ my_compress(PG_FUNCTION_ARGS)
<para>
The reverse of the <function>compress</function> method. Converts the
index representation of the data item into a format that can be
- manipulated by the database.
+ manipulated by the other GiST methods in the operator class.
</para>
<para>
@@ -807,6 +808,72 @@ my_distance(PG_FUNCTION_ARGS)
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><function>fetch</></term>
+ <listitem>
+ <para>
+ Converts the compressed index representation of the data item into the
+ original data type, for index-only scans. The returned data must be an
+ exact, non-lossy copy of the originally indexed value.
+ </para>
+
+ <para>
+ The <acronym>SQL</> declaration of the function must look like this:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION my_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</programlisting>
+
+ The argument is a pointer to a <structname>GISTENTRY</> struct. On
+ entry, its 'key' field contains a non-NULL leaf datum in its
+ compressed form. The return value is another <structname>GISTENTRY</>
+ struct, whose 'key' field contains the same datum in the original,
+ uncompressed form. If the opclass' compress function does nothing for
+ leaf entries, the fetch method can return the argument as is.
+ </para>
+
+ <para>
+ The matching code in the C module could then follow this skeleton:
+
+<programlisting>
+Datum my_fetch(PG_FUNCTION_ARGS);
+PG_FUNCTION_INFO_V1(my_fetch);
+
+Datum
+my_fetch(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ input_data_type *in = DatumGetP(entry->key);
+ fetched_data_type *fetched_data;
+ GISTENTRY *retval;
+
+ retval = palloc(sizeof(GISTENTRY));
+ fetched_data = palloc(sizeof(fetched_data_type));
+
+ /*
+ * Convert 'fetched_data' into the a Datum of the original datatype.
+ */
+
+ /* fill *retval from fetch_data. */
+ gistentryinit(*retval, PointerGetDatum(converted_datum),
+ entry->rel, entry->page, entry->offset, FALSE);
+
+ PG_RETURN_POINTER(retval);
+}
+</programlisting>
+ </para>
+
+ <para>
+ If the compress method is lossy for leaf entries, the operator class
+ cannot support index-only scans, and must not define a 'fetch'
+ function.
+ </para>
+
+ </listitem>
+ </varlistentry>
</variablelist>
<para>
diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml
index 157047a23ab..1c09bae3955 100644
--- a/doc/src/sgml/indexam.sgml
+++ b/doc/src/sgml/indexam.sgml
@@ -274,14 +274,15 @@ amvacuumcleanup (IndexVacuumInfo *info,
<para>
<programlisting>
bool
-amcanreturn (Relation indexRelation);
+amcanreturn (Relation indexRelation, int attno);
</programlisting>
- Check whether the index can support <firstterm>index-only scans</> by
- returning the indexed column values for an index entry in the form of an
- <structname>IndexTuple</structname>. Return TRUE if so, else FALSE. If the index AM can never
- support index-only scans (an example is hash, which stores only
- the hash values not the original data), it is sufficient to set its
- <structfield>amcanreturn</> field to zero in <structname>pg_am</>.
+ Check whether the index can support <firstterm>index-only scans</> on the
+ given column, by returning the indexed column values for an index entry in
+ the form of an <structname>IndexTuple</structname>. The attribute number
+ is 1-based, i.e. the first columns attno is 1. Returns TRUE if supported,
+ else FALSE. If the access method does not support index-only scans at all,
+ the <structfield>amcanreturn</> field in its <structname>pg_am</> row can
+ be set to zero.
</para>
<para>