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. --- src/backend/access/gist/gistproc.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/backend/access/gist/gistproc.c') diff --git a/src/backend/access/gist/gistproc.c b/src/backend/access/gist/gistproc.c index 9fab6c87c05..9d21e3fb947 100644 --- a/src/backend/access/gist/gistproc.c +++ b/src/backend/access/gist/gistproc.c @@ -151,6 +151,16 @@ gist_box_decompress(PG_FUNCTION_ARGS) PG_RETURN_POINTER(PG_GETARG_POINTER(0)); } +/* + * GiST Fetch method for boxes + * do not do anything --- we just return the stored box as is. + */ +Datum +gist_box_fetch(PG_FUNCTION_ARGS) +{ + PG_RETURN_POINTER(PG_GETARG_POINTER(0)); +} + /* * The GiST Penalty method for boxes (also used for points) * @@ -1186,6 +1196,33 @@ gist_point_compress(PG_FUNCTION_ARGS) PG_RETURN_POINTER(entry); } +/* + * GiST Fetch method for point + * + * Get point coordinates from its bounding box coordinates and form new + * gistentry. + */ +Datum +gist_point_fetch(PG_FUNCTION_ARGS) +{ + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + BOX *in = DatumGetBoxP(entry->key); + Point *r; + GISTENTRY *retval; + + retval = palloc(sizeof(GISTENTRY)); + + r = (Point *) palloc(sizeof(Point)); + r->x = in->high.x; + r->y = in->high.y; + gistentryinit(*retval, PointerGetDatum(r), + entry->rel, entry->page, + entry->offset, FALSE); + + PG_RETURN_POINTER(retval); +} + + #define point_point_distance(p1,p2) \ DatumGetFloat8(DirectFunctionCall2(point_distance, \ PointPGetDatum(p1), PointPGetDatum(p2))) -- cgit v1.2.3