]> granicus.if.org Git - postgresql/commitdiff
Fix GiST's killing tuple: GISTScanOpaque->curpos wasn't
authorTeodor Sigaev <teodor@sigaev.ru>
Wed, 22 Oct 2008 12:53:56 +0000 (12:53 +0000)
committerTeodor Sigaev <teodor@sigaev.ru>
Wed, 22 Oct 2008 12:53:56 +0000 (12:53 +0000)
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.

src/backend/access/gist/gistget.c
src/include/access/gist_private.h

index 50d5fc21a47acdf97c0087f888aa2a2bb7b85222..c7d14ecf2327e1ae957e720861b9c0d804e7c621 100644 (file)
@@ -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 ++;
                                        }
index 2d942e54b4930f5190fdda6450ed4a336369eee7..42f9bc76365f7912a6f34ae90e22f27e46755b47 100644 (file)
@@ -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;