Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
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/sgml/gist.sgml
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/sgml/gist.sgml')
-rw-r--r--doc/src/sgml/gist.sgml73
1 files changed, 70 insertions, 3 deletions
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>