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.
REL8_1_STABLE
Teodor Sigaev 17 years ago
parent feb4596697
commit b5f5c89528
  1. 21
      src/backend/access/gist/gistget.c
  2. 6
      src/backend/access/gist/gistscan.c
  3. 12
      src/include/access/gist_private.h

@ -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 ++;
}
}

@ -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();
}

@ -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;

Loading…
Cancel
Save