]> 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:56:25 +0000 (12:56 +0000)
committerTeodor Sigaev <teodor@sigaev.ru>
Wed, 22 Oct 2008 12:56:25 +0000 (12:56 +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/backend/access/gist/gistscan.c
src/include/access/gist_private.h

index feeb84d38d73ff1c29b94671e0e6b7263c38606e..7c041f480bf1ae2fcea691aa622b5971aa87197e 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.52.2.2 2008/08/23 10:43:58 teodor Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.52.2.3 2008/10/22 12:56:25 teodor Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -153,7 +153,11 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
        {
                while( ntids < maxtids && so->curPageData < so->nPageData )
                {
-                       tids[ ntids ] = scan->xs_ctup.t_self = so->pageData[ so->curPageData ];
+                       tids[ ntids ] = scan->xs_ctup.t_self = so->pageData[ so->curPageData ].heapPtr;
+                       ItemPointerSet(&scan->currentItemData,
+                                                          BufferGetBlockNumber(so->curbuf), 
+                                                          so->pageData[ so->curPageData ].pageOffset);
+
                                
                        so->curPageData ++;
                        ntids++;
@@ -246,8 +250,13 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
                        {
                                while( ntids < maxtids && so->curPageData < so->nPageData )
                                {
-                                       tids[ ntids ] = scan->xs_ctup.t_self = so->pageData[ so->curPageData ];
+                                       tids[ ntids ] = scan->xs_ctup.t_self = 
+                                               so->pageData[ so->curPageData ].heapPtr;
                                
+                                       ItemPointerSet(&scan->currentItemData,
+                                                                  BufferGetBlockNumber(so->curbuf), 
+                                                                  so->pageData[ so->curPageData ].pageOffset);
+
                                        so->curPageData ++;
                                        ntids++;
                                }
@@ -291,13 +300,11 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
                                 * we can efficiently resume the index scan later.
                                 */
 
-                               ItemPointerSet(&(scan->currentItemData),
-                                                          BufferGetBlockNumber(so->curbuf), n);
-
                                if (!(ignore_killed_tuples && ItemIdDeleted(PageGetItemId(p, n))))
                                {
                                        it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
-                                       so->pageData[ so->nPageData ] = it->t_tid;
+                                       so->pageData[ so->nPageData ].heapPtr = it->t_tid;
+                                       so->pageData[ so->nPageData ].pageOffset = n;
                                        so->nPageData ++;
                                }
                        }
index 3604debba0f4e2514812f244f175e0244c61b3a8..4ee82d13f59bc9bb67a140152f95e62c695871c0 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.61.2.1 2008/08/23 10:43:58 teodor Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.61.2.2 2008/10/22 12:56:25 teodor Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -185,7 +185,7 @@ gistmarkpos(PG_FUNCTION_ARGS)
        so->markNPageData = so->nPageData;
        so->markCurPageData = so->curPageData;
        if ( so->markNPageData > 0 )
-               memcpy( so->markPageData, so->pageData, sizeof(ItemPointerData) * so->markNPageData );          
+               memcpy( so->markPageData, so->pageData, sizeof(MatchedItemPtr) * so->markNPageData );           
 
        PG_RETURN_VOID();
 }
@@ -239,7 +239,7 @@ gistrestrpos(PG_FUNCTION_ARGS)
        so->nPageData = so->markNPageData;
        so->curPageData = so->markNPageData;
        if ( so->markNPageData > 0 )
-               memcpy( so->pageData, so->markPageData, sizeof(ItemPointerData) * so->markNPageData );          
+               memcpy( so->pageData, so->markPageData, sizeof(MatchedItemPtr) * so->markNPageData );           
 
        PG_RETURN_VOID();
 }
index c1861180d24a93030ec96cbdc81909c2cb212e77..1668f80a9c99c244fcc4a98c148c096ca2863bd4 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.8.2.1 2008/08/23 10:43:58 teodor Exp $
+ * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.8.2.2 2008/10/22 12:56:25 teodor Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -60,6 +60,12 @@ typedef struct GISTSTATE
        TupleDesc       tupdesc;
 } GISTSTATE;
 
+typedef struct MatchedItemPtr 
+{
+       ItemPointerData         heapPtr;
+       OffsetNumber            pageOffset; /* offset in index page */
+} MatchedItemPtr;
+
 /*
  *     When we're doing a scan, we need to keep track of the parent stack
  *     for the marked and current items.
@@ -74,10 +80,10 @@ typedef struct GISTScanOpaqueData
        Buffer          curbuf;
        Buffer          markbuf;
 
-       ItemPointerData pageData[BLCKSZ/sizeof(IndexTupleData)];
+       MatchedItemPtr  pageData[BLCKSZ/sizeof(IndexTupleData)];
        OffsetNumber    nPageData;
        OffsetNumber    curPageData;
-       ItemPointerData markPageData[BLCKSZ/sizeof(IndexTupleData)];
+       MatchedItemPtr  markPageData[BLCKSZ/sizeof(IndexTupleData)];
        OffsetNumber    markNPageData;
        OffsetNumber    markCurPageData;
 } GISTScanOpaqueData;