diff options
author | Heikki Linnakangas | 2015-03-26 17:12:00 +0000 |
---|---|---|
committer | Heikki Linnakangas | 2015-03-26 17:12:00 +0000 |
commit | d04c8ed9044eccebce043143a930617e3998c005 (patch) | |
tree | e0167be995bb28dab91dfb92f1e18609e91a0d3e /doc/src/sgml/gist.sgml | |
parent | 8fa393a6d739796d9f06a7fba91d7e1d0c354879 (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.sgml | 73 |
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> |