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.c14
-rw-r--r--src/backend/access/gist/gistget.c42
-rw-r--r--src/backend/access/hash/hash.c5
-rw-r--r--src/backend/access/index/genam.c20
-rw-r--r--src/backend/access/index/indexam.c8
-rw-r--r--src/backend/access/nbtree/nbtree.c5
6 files changed, 63 insertions, 31 deletions
diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c
index 4fb5ee556c5..af38717340a 100644
--- a/src/backend/access/gin/ginget.c
+++ b/src/backend/access/gin/ginget.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.11 2008/04/10 22:25:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.12 2008/04/13 19:18:13 tgl Exp $
*-------------------------------------------------------------------------
*/
@@ -428,11 +428,14 @@ keyGetItem(Relation index, GinState *ginstate, MemoryContext tempCtx, GinScanKey
* returns true if found
*/
static bool
-scanGetItem(IndexScanDesc scan, ItemPointerData *item)
+scanGetItem(IndexScanDesc scan, ItemPointerData *item, bool *recheck)
{
uint32 i;
GinScanOpaque so = (GinScanOpaque) scan->opaque;
+ /* XXX for the moment, treat all GIN operators as lossy */
+ *recheck = true;
+
ItemPointerSetMin(item);
for (i = 0; i < so->nkeys; i++)
{
@@ -496,13 +499,14 @@ gingetbitmap(PG_FUNCTION_ARGS)
for (;;)
{
ItemPointerData iptr;
+ bool recheck;
CHECK_FOR_INTERRUPTS();
- if (!scanGetItem(scan, &iptr))
+ if (!scanGetItem(scan, &iptr, &recheck))
break;
- tbm_add_tuples(tbm, &iptr, 1, false);
+ tbm_add_tuples(tbm, &iptr, 1, recheck);
ntids++;
}
@@ -528,7 +532,7 @@ gingettuple(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(false);
startScan(scan);
- res = scanGetItem(scan, &scan->xs_ctup.t_self);
+ res = scanGetItem(scan, &scan->xs_ctup.t_self, &scan->xs_recheck);
stopScan(scan);
PG_RETURN_BOOL(res);
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index 4533ff8c85f..8e921395825 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.70 2008/04/10 22:25:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.71 2008/04/13 19:18:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,9 +23,7 @@
static OffsetNumber gistfindnext(IndexScanDesc scan, OffsetNumber n,
ScanDirection dir);
-static int64 gistnext(IndexScanDesc scan, ScanDirection dir,
- ItemPointer tid, TIDBitmap *tbm,
- bool ignore_killed_tuples);
+static int64 gistnext(IndexScanDesc scan, ScanDirection dir, TIDBitmap *tbm);
static bool gistindex_keytest(IndexTuple tuple, IndexScanDesc scan,
OffsetNumber offset);
@@ -100,7 +98,6 @@ gistgettuple(PG_FUNCTION_ARGS)
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
ScanDirection dir = (ScanDirection) PG_GETARG_INT32(1);
GISTScanOpaque so;
- ItemPointerData tid;
bool res;
so = (GISTScanOpaque) scan->opaque;
@@ -113,11 +110,9 @@ gistgettuple(PG_FUNCTION_ARGS)
killtuple(scan->indexRelation, so, &(so->curpos));
/*
- * Get the next tuple that matches the search key. If asked to skip killed
- * tuples, continue looping until we find a non-killed tuple that matches
- * the search key.
+ * Get the next tuple that matches the search key.
*/
- res = (gistnext(scan, dir, &tid, NULL, scan->ignore_killed_tuples) > 0) ? true : false;
+ res = (gistnext(scan, dir, NULL) > 0);
PG_RETURN_BOOL(res);
}
@@ -129,7 +124,7 @@ gistgetbitmap(PG_FUNCTION_ARGS)
TIDBitmap *tbm = (TIDBitmap *) PG_GETARG_POINTER(1);
int64 ntids;
- ntids = gistnext(scan, ForwardScanDirection, NULL, tbm, false);
+ ntids = gistnext(scan, ForwardScanDirection, tbm);
PG_RETURN_INT64(ntids);
}
@@ -140,20 +135,23 @@ gistgetbitmap(PG_FUNCTION_ARGS)
*
* 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.
+ * is returned in scan->xs_ctup.t_self. When invoked from getbitmap,
+ * tbm is non-null and all matching tuples are added to tbm before
+ * returning. In both cases, the function result is the number of
+ * returned tuples.
+ *
+ * If scan specifies to skip killed tuples, continue looping until we find a
+ * non-killed tuple that matches the search key.
*/
static int64
-gistnext(IndexScanDesc scan, ScanDirection dir,
- ItemPointer tid, TIDBitmap *tbm,
- bool ignore_killed_tuples)
+gistnext(IndexScanDesc scan, ScanDirection dir, TIDBitmap *tbm)
{
Page p;
OffsetNumber n;
GISTScanOpaque so;
GISTSearchStack *stk;
IndexTuple it;
+ bool recheck;
GISTPageOpaque opaque;
bool resetoffset = false;
int64 ntids = 0;
@@ -194,7 +192,7 @@ gistnext(IndexScanDesc scan, ScanDirection dir,
if (XLogRecPtrIsInvalid(so->stack->lsn) || !XLByteEQ(so->stack->lsn, PageGetLSN(p)))
{
- /* page changed from last visit or visit first time , reset offset */
+ /* first visit or page changed from last visit, reset offset */
so->stack->lsn = PageGetLSN(p);
resetoffset = true;
@@ -259,6 +257,8 @@ gistnext(IndexScanDesc scan, ScanDirection dir,
for (;;)
{
n = gistfindnext(scan, n, dir);
+ /* XXX for the moment, treat all GIST operators as lossy */
+ recheck = true;
if (!OffsetNumberIsValid(n))
{
@@ -298,15 +298,17 @@ gistnext(IndexScanDesc scan, ScanDirection dir,
ItemPointerSet(&(so->curpos),
BufferGetBlockNumber(so->curbuf), n);
- if (!(ignore_killed_tuples && ItemIdIsDead(PageGetItemId(p, n))))
+ if (!(scan->ignore_killed_tuples &&
+ ItemIdIsDead(PageGetItemId(p, n))))
{
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
ntids++;
if (tbm != NULL)
- tbm_add_tuples(tbm, &it->t_tid, 1, false);
+ tbm_add_tuples(tbm, &it->t_tid, 1, recheck);
else
{
- *tid = scan->xs_ctup.t_self = it->t_tid;
+ scan->xs_ctup.t_self = it->t_tid;
+ scan->xs_recheck = recheck;
LockBuffer(so->curbuf, GIST_UNLOCK);
return ntids; /* always 1 */
diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c
index c090cfef8bb..997eff31058 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.101 2008/04/10 22:25:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.102 2008/04/13 19:18:14 tgl Exp $
*
* NOTES
* This file contains only the public interface routines.
@@ -210,6 +210,9 @@ hashgettuple(PG_FUNCTION_ARGS)
OffsetNumber offnum;
bool res;
+ /* Hash indexes are never lossy (at the moment anyway) */
+ scan->xs_recheck = false;
+
/*
* We hold pin but not lock on current buffer while outside the hash AM.
* Reacquire the read lock here.
diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c
index cafb1e6867a..e8958abca2b 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.67 2008/04/12 23:14:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.68 2008/04/13 19:18:14 tgl Exp $
*
* NOTES
* many of the old access method routines have been turned into
@@ -96,9 +96,9 @@ RelationGetIndexScan(Relation indexRelation,
ItemPointerSetInvalid(&scan->xs_ctup.t_self);
scan->xs_ctup.t_data = NULL;
scan->xs_cbuf = InvalidBuffer;
- scan->xs_prev_xmax = InvalidTransactionId;
- scan->xs_next_hot = InvalidOffsetNumber;
scan->xs_hot_dead = false;
+ scan->xs_next_hot = InvalidOffsetNumber;
+ scan->xs_prev_xmax = InvalidTransactionId;
/*
* Let the AM fill in the key and any opaque data it wants.
@@ -233,7 +233,18 @@ systable_getnext(SysScanDesc sysscan)
HeapTuple htup;
if (sysscan->irel)
+ {
htup = index_getnext(sysscan->iscan, ForwardScanDirection);
+ /*
+ * We currently don't need to support lossy index operators for
+ * any system catalog scan. It could be done here, using the
+ * scan keys to drive the operator calls, if we arranged to save
+ * the heap attnums during systable_beginscan(); this is practical
+ * because we still wouldn't need to support indexes on expressions.
+ */
+ if (htup && sysscan->iscan->xs_recheck)
+ elog(ERROR, "system catalog scans with lossy index conditions are not implemented");
+ }
else
htup = heap_getnext(sysscan->scan, ForwardScanDirection);
@@ -328,6 +339,9 @@ systable_getnext_ordered(SysScanDesc sysscan, ScanDirection direction)
Assert(sysscan->irel);
htup = index_getnext(sysscan->iscan, direction);
+ /* See notes in systable_getnext */
+ if (htup && sysscan->iscan->xs_recheck)
+ elog(ERROR, "system catalog scans with lossy index conditions are not implemented");
return htup;
}
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index 7a06d0074e8..ece3ae8ea40 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.106 2008/04/12 23:14:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.107 2008/04/13 19:18:14 tgl Exp $
*
* INTERFACE ROUTINES
* index_open - open an index relation by relation OID
@@ -402,6 +402,10 @@ index_restrpos(IndexScanDesc scan)
* snapshot, or NULL if no more matching tuples exist. On success,
* the buffer containing the heap tuple is pinned (the pin will be dropped
* at the next index_getnext or index_endscan).
+ *
+ * Note: caller must check scan->xs_recheck, and perform rechecking of the
+ * scan keys if required. We do not do that here because we don't have
+ * enough information to do it efficiently in the general case.
* ----------------
*/
HeapTuple
@@ -455,6 +459,8 @@ index_getnext(IndexScanDesc scan, ScanDirection direction)
/*
* The AM's gettuple proc finds the next index entry matching the
* scan keys, and puts the TID in xs_ctup.t_self (ie, *tid).
+ * It should also set scan->xs_recheck, though we pay no
+ * attention to that here.
*/
found = DatumGetBool(FunctionCall2(procedure,
PointerGetDatum(scan),
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index d96348ace46..24f9b4c77b2 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.157 2008/04/10 22:25:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.158 2008/04/13 19:18:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -240,6 +240,9 @@ btgettuple(PG_FUNCTION_ARGS)
BTScanOpaque so = (BTScanOpaque) scan->opaque;
bool res;
+ /* btree indexes are never lossy */
+ scan->xs_recheck = false;
+
/*
* If we've already initialized this scan, we can just advance it in the
* appropriate direction. If we haven't done so yet, we call a routine to