aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2008-10-22 12:53:56 +0000
committerTeodor Sigaev <teodor@sigaev.ru>2008-10-22 12:53:56 +0000
commitb9856b67a7a762ab5bedfafbda4f654797d83996 (patch)
treecd62a43e225608dfb63cea26407802a4aa608c9a /src
parent361bfc35724aac207f7a013336e058704fbadf60 (diff)
downloadpostgresql-b9856b67a7a762ab5bedfafbda4f654797d83996.tar.gz
postgresql-b9856b67a7a762ab5bedfafbda4f654797d83996.zip
Fix GiST's killing tuple: GISTScanOpaque->curpos wasn't
correctly set. As result, killtuple() marks as dead wrong tuple on page. Bug was introduced by me while fixing possible duplicates during GiST index scan.
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/gist/gistget.c46
-rw-r--r--src/include/access/gist_private.h5
2 files changed, 30 insertions, 21 deletions
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index 50d5fc21a47..c7d14ecf232 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.78 2008/10/20 16:35:14 teodor Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.79 2008/10/22 12:53:56 teodor Exp $
*
*-------------------------------------------------------------------------
*/
@@ -51,7 +51,7 @@ killtuple(Relation r, GISTScanOpaque so, ItemPointer iptr)
for (offset = FirstOffsetNumber; offset <= maxoff; offset = OffsetNumberNext(offset))
{
- IndexTuple ituple = (IndexTuple) PageGetItem(p, PageGetItemId(p, offset));
+ IndexTuple ituple = (IndexTuple) PageGetItem(p, PageGetItemId(p, offset));
if (ItemPointerEquals(&(ituple->t_tid), iptr))
{
@@ -139,24 +139,28 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm)
if ( so->qual_ok == false )
return 0;
- if (ItemPointerIsValid(&so->curpos) == false)
+ if ( so->curbuf == InvalidBuffer )
{
- /* Being asked to fetch the first entry, so start at the root */
- Assert(so->curbuf == InvalidBuffer);
- Assert(so->stack == NULL);
+ if (ItemPointerIsValid(&so->curpos) == false)
+ {
+ /* Being asked to fetch the first entry, so start at the root */
+ Assert(so->curbuf == InvalidBuffer);
+ Assert(so->stack == NULL);
- so->curbuf = ReadBuffer(scan->indexRelation, GIST_ROOT_BLKNO);
+ so->curbuf = ReadBuffer(scan->indexRelation, GIST_ROOT_BLKNO);
- stk = so->stack = (GISTSearchStack *) palloc0(sizeof(GISTSearchStack));
+ stk = so->stack = (GISTSearchStack *) palloc0(sizeof(GISTSearchStack));
- stk->next = NULL;
- stk->block = GIST_ROOT_BLKNO;
+ stk->next = NULL;
+ stk->block = GIST_ROOT_BLKNO;
- pgstat_count_index_scan(scan->indexRelation);
- }
- else if (so->curbuf == InvalidBuffer)
- {
- return 0;
+ pgstat_count_index_scan(scan->indexRelation);
+ }
+ else
+ {
+ /* scan is finished */
+ return 0;
+ }
}
/*
@@ -171,8 +175,13 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm)
if ( so->curPageData < so->nPageData )
{
- scan->xs_ctup.t_self = so->pageData[ so->curPageData ].iptr;
+ scan->xs_ctup.t_self = so->pageData[ so->curPageData ].heapPtr;
scan->xs_recheck = so->pageData[ so->curPageData ].recheck;
+
+ ItemPointerSet(&so->curpos,
+ BufferGetBlockNumber(so->curbuf),
+ so->pageData[ so->curPageData ].pageOffset);
+
so->curPageData ++;
return 1;
@@ -307,8 +316,6 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm)
* 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 (!(scan->ignore_killed_tuples &&
ItemIdIsDead(PageGetItemId(p, n))))
@@ -319,7 +326,8 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm)
tbm_add_tuples(tbm, &it->t_tid, 1, scan->xs_recheck);
else
{
- so->pageData[ so->nPageData ].iptr = it->t_tid;
+ so->pageData[ so->nPageData ].heapPtr = it->t_tid;
+ so->pageData[ so->nPageData ].pageOffset = n;
so->pageData[ so->nPageData ].recheck = scan->xs_recheck;
so->nPageData ++;
}
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index 2d942e54b49..42f9bc76365 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.34 2008/10/20 13:39:44 teodor Exp $
+ * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.35 2008/10/22 12:53:56 teodor Exp $
*
*-------------------------------------------------------------------------
*/
@@ -60,7 +60,8 @@ typedef struct GISTSTATE
typedef struct ItemResult
{
- ItemPointerData iptr;
+ ItemPointerData heapPtr;
+ OffsetNumber pageOffset; /* offset in index page */
bool recheck;
} ItemResult;