aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access')
-rw-r--r--src/backend/access/gin/ginget.c33
-rw-r--r--src/backend/access/gist/gistget.c55
-rw-r--r--src/backend/access/hash/hash.c76
-rw-r--r--src/backend/access/index/genam.c3
-rw-r--r--src/backend/access/index/indexam.c47
-rw-r--r--src/backend/access/nbtree/nbtree.c55
6 files changed, 122 insertions, 147 deletions
diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c
index 31464ab2bc3..4fb5ee556c5 100644
--- a/src/backend/access/gin/ginget.c
+++ b/src/backend/access/gin/ginget.c
@@ -8,13 +8,15 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.10 2008/01/01 19:45:46 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.11 2008/04/10 22:25:25 tgl Exp $
*-------------------------------------------------------------------------
*/
#include "postgres.h"
+
#include "access/gin.h"
#include "catalog/index.h"
+#include "miscadmin.h"
#include "utils/memutils.h"
static bool
@@ -476,34 +478,37 @@ scanGetItem(IndexScanDesc scan, ItemPointerData *item)
#define GinIsVoidRes(s) ( ((GinScanOpaque) scan->opaque)->isVoidRes == true )
Datum
-gingetmulti(PG_FUNCTION_ARGS)
+gingetbitmap(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);
+ TIDBitmap *tbm = (TIDBitmap *) PG_GETARG_POINTER(1);
+ int64 ntids;
if (GinIsNewKey(scan))
newScanKey(scan);
- *returned_tids = 0;
-
if (GinIsVoidRes(scan))
- PG_RETURN_BOOL(false);
+ PG_RETURN_INT64(0);
startScan(scan);
- do
+ ntids = 0;
+ for (;;)
{
- if (scanGetItem(scan, tids + *returned_tids))
- (*returned_tids)++;
- else
+ ItemPointerData iptr;
+
+ CHECK_FOR_INTERRUPTS();
+
+ if (!scanGetItem(scan, &iptr))
break;
- } while (*returned_tids < max_tids);
+
+ tbm_add_tuples(tbm, &iptr, 1, false);
+ ntids++;
+ }
stopScan(scan);
- PG_RETURN_BOOL(*returned_tids == max_tids);
+ PG_RETURN_INT64(ntids);
}
Datum
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index 22a7d0ceae6..4533ff8c85f 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.69 2008/01/01 19:45:46 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.70 2008/04/10 22:25:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,13 +16,16 @@
#include "access/gist_private.h"
#include "executor/execdebug.h"
+#include "miscadmin.h"
#include "pgstat.h"
#include "utils/memutils.h"
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 int64 gistnext(IndexScanDesc scan, ScanDirection dir,
+ ItemPointer tid, TIDBitmap *tbm,
+ bool ignore_killed_tuples);
static bool gistindex_keytest(IndexTuple tuple, IndexScanDesc scan,
OffsetNumber offset);
@@ -114,32 +117,37 @@ gistgettuple(PG_FUNCTION_ARGS)
* 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;
+ res = (gistnext(scan, dir, &tid, NULL, scan->ignore_killed_tuples) > 0) ? true : false;
PG_RETURN_BOOL(res);
}
Datum
-gistgetmulti(PG_FUNCTION_ARGS)
+gistgetbitmap(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);
+ TIDBitmap *tbm = (TIDBitmap *) PG_GETARG_POINTER(1);
+ int64 ntids;
- *returned_tids = gistnext(scan, ForwardScanDirection, tids, max_tids, false);
+ ntids = gistnext(scan, ForwardScanDirection, NULL, tbm, false);
- PG_RETURN_BOOL(*returned_tids == max_tids);
+ PG_RETURN_INT64(ntids);
}
/*
- * 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.
+ * Fetch tuple(s) that match the search key; this can be invoked
+ * either to fetch the first such tuple or subsequent matching tuples.
+ *
+ * This function is used by both gistgettuple and gistgetbitmap. When
+ * invoked from gistgettuple, tbm is null and the next matching tuple
+ * is returned in *tid. When invoked from getbitmap, tid is null and
+ * all matching tuples are added to tbm. In both cases, the function
+ * result is the number of returned tuples.
*/
-static int
-gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids,
- int maxtids, bool ignore_killed_tuples)
+static int64
+gistnext(IndexScanDesc scan, ScanDirection dir,
+ ItemPointer tid, TIDBitmap *tbm,
+ bool ignore_killed_tuples)
{
Page p;
OffsetNumber n;
@@ -148,7 +156,7 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids,
IndexTuple it;
GISTPageOpaque opaque;
bool resetoffset = false;
- int ntids = 0;
+ int64 ntids = 0;
so = (GISTScanOpaque) scan->opaque;
@@ -174,6 +182,8 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids,
for (;;)
{
+ CHECK_FOR_INTERRUPTS();
+
/* First of all, we need lock buffer */
Assert(so->curbuf != InvalidBuffer);
LockBuffer(so->curbuf, GIST_SHARE);
@@ -285,20 +295,21 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids,
* return success. Note that we keep "curbuf" pinned so that
* we can efficiently resume the index scan later.
*/
-
ItemPointerSet(&(so->curpos),
BufferGetBlockNumber(so->curbuf), n);
if (!(ignore_killed_tuples && ItemIdIsDead(PageGetItemId(p, n))))
{
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
- tids[ntids] = scan->xs_ctup.t_self = it->t_tid;
ntids++;
-
- if (ntids == maxtids)
+ if (tbm != NULL)
+ tbm_add_tuples(tbm, &it->t_tid, 1, false);
+ else
{
+ *tid = scan->xs_ctup.t_self = it->t_tid;
+
LockBuffer(so->curbuf, GIST_UNLOCK);
- return ntids;
+ return ntids; /* always 1 */
}
}
}
@@ -308,7 +319,6 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids,
* We've found an entry in an internal node whose key is
* consistent with the search key, so push it to stack
*/
-
stk = (GISTSearchStack *) palloc(sizeof(GISTSearchStack));
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
@@ -318,7 +328,6 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids,
stk->next = so->stack->next;
so->stack->next = stk;
-
}
if (ScanDirectionIsBackward(dir))
diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c
index 01da35ec9f2..c090cfef8bb 100644
--- a/src/backend/access/hash/hash.c
+++ b/src/backend/access/hash/hash.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.100 2008/03/16 23:15:08 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.101 2008/04/10 22:25:25 tgl Exp $
*
* NOTES
* This file contains only the public interface routines.
@@ -22,6 +22,7 @@
#include "access/hash.h"
#include "catalog/index.h"
#include "commands/vacuum.h"
+#include "miscadmin.h"
#include "optimizer/cost.h"
#include "optimizer/plancat.h"
@@ -275,72 +276,51 @@ hashgettuple(PG_FUNCTION_ARGS)
/*
- * hashgetmulti() -- get multiple tuples at once
- *
- * This is a somewhat generic implementation: it avoids lock reacquisition
- * overhead, but there's no smarts about picking especially good stopping
- * points such as index page boundaries.
+ * hashgetbitmap() -- get all tuples at once
*/
Datum
-hashgetmulti(PG_FUNCTION_ARGS)
+hashgetbitmap(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);
+ TIDBitmap *tbm = (TIDBitmap *) PG_GETARG_POINTER(1);
HashScanOpaque so = (HashScanOpaque) scan->opaque;
- Relation rel = scan->indexRelation;
- bool res = true;
- int32 ntids = 0;
+ bool res;
+ int64 ntids = 0;
- /*
- * We hold pin but not lock on current buffer while outside the hash AM.
- * Reacquire the read lock here.
- */
- if (BufferIsValid(so->hashso_curbuf))
- _hash_chgbufaccess(rel, so->hashso_curbuf, HASH_NOLOCK, HASH_READ);
+ res = _hash_first(scan, ForwardScanDirection);
- while (ntids < max_tids)
+ while (res)
{
- /*
- * Start scan, or advance to next tuple.
- */
- if (ItemPointerIsValid(&(so->hashso_curpos)))
- res = _hash_next(scan, ForwardScanDirection);
- else
- res = _hash_first(scan, ForwardScanDirection);
+ bool add_tuple;
+
+ CHECK_FOR_INTERRUPTS();
/*
* Skip killed tuples if asked to.
*/
if (scan->ignore_killed_tuples)
{
- while (res)
- {
- Page page;
- OffsetNumber offnum;
-
- offnum = ItemPointerGetOffsetNumber(&(so->hashso_curpos));
- page = BufferGetPage(so->hashso_curbuf);
- if (!ItemIdIsDead(PageGetItemId(page, offnum)))
- break;
- res = _hash_next(scan, ForwardScanDirection);
- }
+ Page page;
+ OffsetNumber offnum;
+
+ offnum = ItemPointerGetOffsetNumber(&(so->hashso_curpos));
+ page = BufferGetPage(so->hashso_curbuf);
+ add_tuple = !ItemIdIsDead(PageGetItemId(page, offnum));
}
+ else
+ add_tuple = true;
- if (!res)
- break;
/* Save tuple ID, and continue scanning */
- tids[ntids] = scan->xs_ctup.t_self;
- ntids++;
- }
+ if (add_tuple)
+ {
+ tbm_add_tuples(tbm, &scan->xs_ctup.t_self, 1, false);
+ ntids++;
+ }
- /* Release read lock on current buffer, but keep it pinned */
- if (BufferIsValid(so->hashso_curbuf))
- _hash_chgbufaccess(rel, so->hashso_curbuf, HASH_READ, HASH_NOLOCK);
+ res = _hash_next(scan, ForwardScanDirection);
+ }
- *returned_tids = ntids;
- PG_RETURN_BOOL(res);
+ PG_RETURN_INT64(ntids);
}
diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c
index a4395cb240e..8877938322d 100644
--- a/src/backend/access/index/genam.c
+++ b/src/backend/access/index/genam.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.65 2008/03/26 21:10:37 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.66 2008/04/10 22:25:25 tgl Exp $
*
* NOTES
* many of the old access method routines have been turned into
@@ -88,7 +88,6 @@ RelationGetIndexScan(Relation indexRelation,
else
scan->keyData = NULL;
- scan->is_multiscan = false; /* caller may change this */
scan->kill_prior_tuple = false;
scan->ignore_killed_tuples = true; /* default setting */
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index c4739aa1cd1..d59f1529db1 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -8,20 +8,20 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.104 2008/03/26 21:10:37 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.105 2008/04/10 22:25:25 tgl Exp $
*
* INTERFACE ROUTINES
* index_open - open an index relation by relation OID
* index_close - close an index relation
* index_beginscan - start a scan of an index with amgettuple
- * index_beginscan_multi - start a scan of an index with amgetmulti
+ * index_beginscan_bitmap - start a scan of an index with amgetbitmap
* index_rescan - restart a scan of an index
* index_endscan - end a scan
* index_insert - insert an index tuple into a relation
* index_markpos - mark a scan position
* index_restrpos - restore a scan position
* index_getnext - get the next tuple from a scan
- * index_getmulti - get multiple tuples from a scan
+ * index_getbitmap - get all tuples from a scan
* index_bulk_delete - bulk deletion of index tuples
* index_vacuum_cleanup - post-deletion cleanup of an index
* index_getprocid - get a support procedure OID
@@ -227,7 +227,6 @@ index_beginscan(Relation heapRelation,
* Save additional parameters into the scandesc. Everything else was set
* up by RelationGetIndexScan.
*/
- scan->is_multiscan = false;
scan->heapRelation = heapRelation;
scan->xs_snapshot = snapshot;
@@ -235,15 +234,15 @@ index_beginscan(Relation heapRelation,
}
/*
- * index_beginscan_multi - start a scan of an index with amgetmulti
+ * index_beginscan_bitmap - start a scan of an index with amgetbitmap
*
* As above, caller had better be holding some lock on the parent heap
* relation, even though it's not explicitly mentioned here.
*/
IndexScanDesc
-index_beginscan_multi(Relation indexRelation,
- Snapshot snapshot,
- int nkeys, ScanKey key)
+index_beginscan_bitmap(Relation indexRelation,
+ Snapshot snapshot,
+ int nkeys, ScanKey key)
{
IndexScanDesc scan;
@@ -253,7 +252,6 @@ index_beginscan_multi(Relation indexRelation,
* Save additional parameters into the scandesc. Everything else was set
* up by RelationGetIndexScan.
*/
- scan->is_multiscan = true;
scan->xs_snapshot = snapshot;
return scan;
@@ -676,44 +674,39 @@ index_getnext_indexitem(IndexScanDesc scan,
}
/* ----------------
- * index_getmulti - get multiple tuples from an index scan
+ * index_getbitmap - get all tuples at once from an index scan
*
- * Collects the TIDs of multiple heap tuples satisfying the scan keys.
+ * Adds the TIDs of all heap tuples satisfying the scan keys to a bitmap.
* Since there's no interlock between the index scan and the eventual heap
* access, this is only safe to use with MVCC-based snapshots: the heap
* item slot could have been replaced by a newer tuple by the time we get
* to it.
*
- * A TRUE result indicates more calls should occur; a FALSE result says the
- * scan is done. *returned_tids could be zero or nonzero in either case.
+ * Returns the number of matching tuples found.
* ----------------
*/
-bool
-index_getmulti(IndexScanDesc scan,
- ItemPointer tids, int32 max_tids,
- int32 *returned_tids)
+int64
+index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap)
{
FmgrInfo *procedure;
- bool found;
+ int64 ntids;
SCAN_CHECKS;
- GET_SCAN_PROCEDURE(amgetmulti);
+ GET_SCAN_PROCEDURE(amgetbitmap);
/* just make sure this is false... */
scan->kill_prior_tuple = false;
/*
- * have the am's getmulti proc do all the work.
+ * have the am's getbitmap proc do all the work.
*/
- found = DatumGetBool(FunctionCall4(procedure,
- PointerGetDatum(scan),
- PointerGetDatum(tids),
- Int32GetDatum(max_tids),
- PointerGetDatum(returned_tids)));
+ ntids = DatumGetInt64(FunctionCall2(procedure,
+ PointerGetDatum(scan),
+ PointerGetDatum(bitmap)));
- pgstat_count_index_tuples(scan->indexRelation, *returned_tids);
+ pgstat_count_index_tuples(scan->indexRelation, ntids);
- return found;
+ return ntids;
}
/* ----------------
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index 5cfa8f315d7..d96348ace46 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.156 2008/01/01 19:45:46 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.157 2008/04/10 22:25:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,6 +22,7 @@
#include "access/nbtree.h"
#include "catalog/index.h"
#include "commands/vacuum.h"
+#include "miscadmin.h"
#include "storage/freespace.h"
#include "storage/lmgr.h"
#include "utils/memutils.h"
@@ -278,42 +279,29 @@ btgettuple(PG_FUNCTION_ARGS)
}
/*
- * btgetmulti() -- get multiple tuples at once
- *
- * In the current implementation there seems no strong reason to stop at
- * index page boundaries; we just press on until we fill the caller's buffer
- * or run out of matches.
+ * btgetbitmap() -- gets all matching tuples, and adds them to a bitmap
*/
Datum
-btgetmulti(PG_FUNCTION_ARGS)
+btgetbitmap(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);
+ TIDBitmap *tbm = (TIDBitmap *) PG_GETARG_POINTER(1);
BTScanOpaque so = (BTScanOpaque) scan->opaque;
- bool res = true;
- int32 ntids = 0;
-
- if (max_tids <= 0) /* behave correctly in boundary case */
- PG_RETURN_BOOL(true);
+ int64 ntids = 0;
+ ItemPointer heapTid;
- /* If we haven't started the scan yet, fetch the first page & tuple. */
- if (!BTScanPosIsValid(so->currPos))
+ /* Fetch the first page & tuple. */
+ if (!_bt_first(scan, ForwardScanDirection))
{
- res = _bt_first(scan, ForwardScanDirection);
- if (!res)
- {
- /* empty scan */
- *returned_tids = ntids;
- PG_RETURN_BOOL(res);
- }
- /* Save tuple ID, and continue scanning */
- tids[ntids] = scan->xs_ctup.t_self;
- ntids++;
+ /* empty scan */
+ PG_RETURN_INT64(0);
}
+ /* Save tuple ID, and continue scanning */
+ heapTid = &scan->xs_ctup.t_self;
+ tbm_add_tuples(tbm, heapTid, 1, false);
+ ntids++;
- while (ntids < max_tids)
+ for (;;)
{
/*
* Advance to next tuple within page. This is the same as the easy
@@ -321,19 +309,20 @@ btgetmulti(PG_FUNCTION_ARGS)
*/
if (++so->currPos.itemIndex > so->currPos.lastItem)
{
+ CHECK_FOR_INTERRUPTS();
+
/* let _bt_next do the heavy lifting */
- res = _bt_next(scan, ForwardScanDirection);
- if (!res)
+ if (!_bt_next(scan, ForwardScanDirection))
break;
}
/* Save tuple ID, and continue scanning */
- tids[ntids] = so->currPos.items[so->currPos.itemIndex].heapTid;
+ heapTid = &so->currPos.items[so->currPos.itemIndex].heapTid;
+ tbm_add_tuples(tbm, heapTid, 1, false);
ntids++;
}
- *returned_tids = ntids;
- PG_RETURN_BOOL(res);
+ PG_RETURN_INT64(ntids);
}
/*