aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2008-10-22 12:55:59 +0000
committerTeodor Sigaev <teodor@sigaev.ru>2008-10-22 12:55:59 +0000
commit8a47932c3ea47f1dce8df10dfc424a199ada9110 (patch)
treed6654ca2fe4dac52264b4c66eabdf79cca6f3f55
parentf189a122265a964cdd7f5ce44447afb9f45f1aa0 (diff)
downloadpostgresql-8a47932c3ea47f1dce8df10dfc424a199ada9110.tar.gz
postgresql-8a47932c3ea47f1dce8df10dfc424a199ada9110.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.
-rw-r--r--src/backend/access/gist/gistget.c21
-rw-r--r--src/backend/access/gist/gistscan.c6
-rw-r--r--src/include/access/gist_private.h12
3 files changed, 26 insertions, 13 deletions
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index ebc41185cbc..ea4d06c232d 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.62.2.1 2008/08/23 10:41:38 teodor Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.62.2.2 2008/10/22 12:55:59 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++;
@@ -247,8 +251,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++;
}
@@ -293,13 +302,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 ++;
}
}
diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c
index 4864fd1248d..aeb1a8282c8 100644
--- a/src/backend/access/gist/gistscan.c
+++ b/src/backend/access/gist/gistscan.c
@@ -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.65.2.1 2008/08/23 10:41:38 teodor Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.65.2.2 2008/10/22 12:55:59 teodor Exp $
*
*-------------------------------------------------------------------------
*/
@@ -154,7 +154,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();
}
@@ -208,7 +208,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();
}
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index ee94875a342..cab33bc9b60 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.24.2.1 2008/08/23 10:41:38 teodor Exp $
+ * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.24.2.2 2008/10/22 12:55:59 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;