From 1dcf6fdf1bd7fb2501445fa2ebfa57e04273e848 Mon Sep 17 00:00:00 2001 From: Teodor Sigaev Date: Sat, 23 Aug 2008 10:37:24 +0000 Subject: Fix possible duplicate tuples while GiST scan. Now page is processed at once and ItemPointers are collected in memory. Remove tuple's killing by killtuple() if tuple was moved to another page - it could produce unaceptable overhead. Backpatch up to 8.1 because the bug was introduced by GiST's concurrency support. --- src/backend/access/gist/gistscan.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/backend/access/gist/gistscan.c') diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c index 65833eabf71..ac3ea446ded 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.70 2008/06/19 00:46:03 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.71 2008/08/23 10:37:24 teodor Exp $ * *------------------------------------------------------------------------- */ @@ -63,6 +63,7 @@ gistrescan(PG_FUNCTION_ARGS) ReleaseBuffer(so->markbuf); so->markbuf = InvalidBuffer; } + } else { @@ -83,6 +84,7 @@ gistrescan(PG_FUNCTION_ARGS) */ ItemPointerSetInvalid(&so->curpos); ItemPointerSetInvalid(&so->markpos); + so->nPageData = so->curPageData = 0; /* Update scan key, if a new one is given */ if (key && scan->numberOfKeys > 0) @@ -150,6 +152,11 @@ gistmarkpos(PG_FUNCTION_ARGS) so->markbuf = so->curbuf; } + so->markNPageData = so->nPageData; + so->markCurPageData = so->curPageData; + if ( so->markNPageData > 0 ) + memcpy( so->markPageData, so->pageData, sizeof(ItemResult) * so->markNPageData ); + PG_RETURN_VOID(); } @@ -199,6 +206,11 @@ gistrestrpos(PG_FUNCTION_ARGS) so->curbuf = so->markbuf; } + so->nPageData = so->markNPageData; + so->curPageData = so->markNPageData; + if ( so->markNPageData > 0 ) + memcpy( so->pageData, so->markPageData, sizeof(ItemResult) * so->markNPageData ); + PG_RETURN_VOID(); } -- cgit v1.2.3