Hi,
Here is a patch by Heikki Linnakangas with changes for amgetmulti index
access method to amgetbitmap, which returns all matching tuples at once.
The patch also introduces support for candidate matches. The original
post is here:
http://archives.postgresql.org/pgsql-patches/2007-03/msg00163.php
I've made minor changes to the patch:
- fixed all rejects when applying it to the current CVS head.
- fixed counting ntids in gistnext if TIDBitmap is not null.
- added missing expected/bitmapops.out
It passes all regression tests on my system.
Regards,
--
Alexey Klyukin http://www.commandprompt.com/
The PostgreSQL Company - Command Prompt, Inc.
diff -c -N -r ./src/backend/access/gin/ginget.c ../pgsql.new/src/backend/access/gin/ginget.c
*** ./src/backend/access/gin/ginget.c 2007-06-19 14:37:49.0 +0300
--- ../pgsql.new/src/backend/access/gin/ginget.c 2007-06-19 14:41:46.0 +0300
***
*** 476,509
#define GinIsVoidRes(s) ( ((GinScanOpaque) scan-opaque)-isVoidRes == true )
Datum
! gingetmulti(PG_FUNCTION_ARGS)
{
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
! ItemPointer tids = (ItemPointer) PG_GETARG_POINTER(1);
! int32 max_tids = PG_GETARG_INT32(2);
! int32 *returned_tids = (int32 *) PG_GETARG_POINTER(3);
if (GinIsNewKey(scan))
newScanKey(scan);
- *returned_tids = 0;
-
if (GinIsVoidRes(scan))
! PG_RETURN_BOOL(false);
startScan(scan);
! do
{
! if (scanGetItem(scan, tids + *returned_tids))
! (*returned_tids)++;
! else
break;
! } while (*returned_tids max_tids);
stopScan(scan);
! PG_RETURN_BOOL(*returned_tids == max_tids);
}
Datum
--- 476,510
#define GinIsVoidRes(s) ( ((GinScanOpaque) scan-opaque)-isVoidRes == true )
Datum
! gingetbitmap(PG_FUNCTION_ARGS)
{
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
! TIDBitmap *tbm = (TIDBitmap *) PG_GETARG_POINTER(1);
! int32 ntids;
if (GinIsNewKey(scan))
newScanKey(scan);
if (GinIsVoidRes(scan))
! PG_RETURN_INT32(0);
startScan(scan);
! ntids = 0;
! for(;;)
{
! ItemPointerData iptr;
!
! if (!scanGetItem(scan, iptr))
break;
!
! ntids++;
! tbm_add_tuples(tbm, iptr, 1, false);
! }
stopScan(scan);
! PG_RETURN_INT32(ntids);
}
Datum
diff -c -N -r ./src/backend/access/gist/gistget.c ../pgsql.new/src/backend/access/gist/gistget.c
*** ./src/backend/access/gist/gistget.c 2007-06-19 14:37:49.0 +0300
--- ../pgsql.new/src/backend/access/gist/gistget.c 2007-06-19 14:41:46.0 +0300
***
*** 22,28
static OffsetNumber gistfindnext(IndexScanDesc scan, OffsetNumber n,
ScanDirection dir);
! static int gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, bool ignore_killed_tuples);
static bool gistindex_keytest(IndexTuple tuple, IndexScanDesc scan,
OffsetNumber offset);
--- 22,30
static OffsetNumber gistfindnext(IndexScanDesc scan, OffsetNumber n,
ScanDirection dir);
! static int gistnext(IndexScanDesc scan, ScanDirection dir,
! ItemPointer tid, TIDBitmap *tbm,
! bool ignore_killed_tuples);
static bool gistindex_keytest(IndexTuple tuple, IndexScanDesc scan,
OffsetNumber offset);
***
*** 114,145
* tuples, continue looping until we find a non-killed tuple that matches
* the search key.
*/
! res = (gistnext(scan, dir, tid, 1, scan-ignore_killed_tuples)) ? true : false;
PG_RETURN_BOOL(res);
}
Datum
! gistgetmulti(PG_FUNCTION_ARGS)
{
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
! ItemPointer tids = (ItemPointer) PG_GETARG_POINTER(1);
! int32 max_tids = PG_GETARG_INT32(2);
! int32 *returned_tids = (int32 *) PG_GETARG_POINTER(3);
! *returned_tids = gistnext(scan, ForwardScanDirection, tids, max_tids, false);
! PG_RETURN_BOOL(*returned_tids == max_tids);
}
/*
* Fetch a tuples that matchs the search key; this can be invoked
* either to fetch the first such tuple or subsequent matching
! * tuples. Returns true iff a matching tuple was found.
*/
static int
! gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids,
! int maxtids, bool ignore_killed_tuples)
{
Page p;
OffsetNumber n;
--- 116,152
* tuples, continue looping until we find a non-killed tuple that matches
* the search key.
*/
! res = (gistnext(scan, dir, tid, NULL, scan-ignore_killed_tuples)) ? true : false;
PG_RETURN_BOOL(res);
}
Datum
! gistgetbitmap(PG_FUNCTION_ARGS)
{
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
! TIDBitmap *tbm = (TIDBitmap *) PG_GETARG_POINTER(1);
! int32 ntids;
! ntids = gistnext(scan, ForwardScanDirection, NULL, tbm, false);
! PG_RETURN_INT32(ntids);
}
/*
* Fetch a tuples that matchs the search key; this can be invoked
* either to fetch the first such tuple