From d04c8ed9044eccebce043143a930617e3998c005 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas
Date: Thu, 26 Mar 2015 19:12:00 +0200
Subject: 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.
---
doc/src/sgml/catalogs.sgml | 4 +--
doc/src/sgml/gist.sgml | 73 ++++++++++++++++++++++++++++++++++++++++++++--
doc/src/sgml/indexam.sgml | 15 +++++-----
3 files changed, 80 insertions(+), 12 deletions(-)
(limited to 'doc/src')
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 @@
amcanreturnregprocpg_proc.oid
- Function to check whether index supports index-only scans,
- or zero if none
+ Function to check whether an index column supports index-only
+ scans. Can be zero if index-only scans are never supported.
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);
There are seven methods that an index operator class for
- GiST must provide, and an eighth that is optional.
+ GiST must provide, and two that are optional.
Correctness of the index is ensured
by proper implementation of the same>, consistent>
and 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 CREATE OPERATOR CLASS> command can be used.
The optional eighth method is distance>, which is needed
if the operator class wishes to support ordered scans (nearest-neighbor
- searches).
+ searches). The optional ninth method fetch> is needed if the
+ operator class wishes to support index-only scans.
@@ -506,7 +507,7 @@ my_compress(PG_FUNCTION_ARGS)
The reverse of the compress 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.
@@ -807,6 +808,72 @@ my_distance(PG_FUNCTION_ARGS)
+
+ fetch>
+
+
+ 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.
+
+
+
+ The SQL> declaration of the function must look like this:
+
+
+CREATE OR REPLACE FUNCTION my_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+
+
+ The argument is a pointer to a GISTENTRY> struct. On
+ entry, its 'key' field contains a non-NULL leaf datum in its
+ compressed form. The return value is another 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.
+
+
+
+ The matching code in the C module could then follow this skeleton:
+
+
+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);
+}
+
+
+
+
+ If the compress method is lossy for leaf entries, the operator class
+ cannot support index-only scans, and must not define a 'fetch'
+ function.
+
+
+
+
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,
bool
-amcanreturn (Relation indexRelation);
+amcanreturn (Relation indexRelation, int attno);
- Check whether the index can support index-only scans> by
- returning the indexed column values for an index entry in the form of an
- IndexTuple. 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
- amcanreturn> field to zero in pg_am>.
+ Check whether the index can support index-only scans> on the
+ given column, by returning the indexed column values for an index entry in
+ the form of an IndexTuple. 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 amcanreturn> field in its pg_am> row can
+ be set to zero.
--
cgit v1.2.3