1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-27 22:56:53 +03:00

Fix missing rows in query

update a=.. where a... with GiST index on column 'a'
Backpatch from 8.0 branch
This commit is contained in:
Teodor Sigaev 2005-08-30 08:48:16 +00:00
parent 26f1202ca3
commit ba5f900b3d
3 changed files with 43 additions and 20 deletions

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.96 2002/09/04 20:31:09 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.96.2.1 2005/08/30 08:48:16 teodor Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -502,7 +502,7 @@ gistlayerinsert(Relation r, BlockNumber blkno,
* changed beginning from 'child' offset * changed beginning from 'child' offset
*/ */
if (ret & SPLITED) if (ret & SPLITED)
gistadjscans(r, GISTOP_SPLIT, blkno, child); gistadjscans(r, GISTOP_SPLIT, nblkno, FirstOffsetNumber);
} }
ret = INSERTED; ret = INSERTED;
@ -1437,6 +1437,9 @@ gistnewroot(Relation r, IndexTuple *itup, int len)
Page p; Page p;
b = ReadBuffer(r, GISTP_ROOT); b = ReadBuffer(r, GISTP_ROOT);
gistadjscans(r, GISTOP_SPLIT, GISTP_ROOT, FirstOffsetNumber);
GISTInitBuffer(b, 0); GISTInitBuffer(b, 0);
p = BufferGetPage(b); p = BufferGetPage(b);

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.35 2002/09/04 20:31:09 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.35.2.1 2005/08/30 08:48:16 teodor Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -167,10 +167,18 @@ gistnext(IndexScanDesc s, ScanDirection dir)
maxoff = PageGetMaxOffsetNumber(p); maxoff = PageGetMaxOffsetNumber(p);
po = (GISTPageOpaque) PageGetSpecialPointer(p); po = (GISTPageOpaque) PageGetSpecialPointer(p);
if ( stk->gs_child == InvalidOffsetNumber ) {
/* rescan page */
if (ScanDirectionIsBackward(dir))
n = PageGetMaxOffsetNumber(p);
else
n = FirstOffsetNumber;
} else {
if (ScanDirectionIsBackward(dir)) if (ScanDirectionIsBackward(dir))
n = OffsetNumberPrev(stk->gs_child); n = OffsetNumberPrev(stk->gs_child);
else else
n = OffsetNumberNext(stk->gs_child); n = OffsetNumberNext(stk->gs_child);
}
so->s_stack = stk->gs_parent; so->s_stack = stk->gs_parent;
pfree(stk); pfree(stk);

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.43 2002/06/20 20:29:24 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.43.2.1 2005/08/30 08:48:16 teodor Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -24,7 +24,7 @@ static void gistregscan(IndexScanDesc s);
static void gistdropscan(IndexScanDesc s); static void gistdropscan(IndexScanDesc s);
static void gistadjone(IndexScanDesc s, int op, BlockNumber blkno, static void gistadjone(IndexScanDesc s, int op, BlockNumber blkno,
OffsetNumber offnum); OffsetNumber offnum);
static void adjuststack(GISTSTACK *stk, BlockNumber blkno); static void adjuststack(GISTSTACK *stk, int op,BlockNumber blkno, OffsetNumber offnum);
static void adjustiptr(IndexScanDesc s, ItemPointer iptr, static void adjustiptr(IndexScanDesc s, ItemPointer iptr,
int op, BlockNumber blkno, OffsetNumber offnum); int op, BlockNumber blkno, OffsetNumber offnum);
@ -319,11 +319,8 @@ gistadjone(IndexScanDesc s,
so = (GISTScanOpaque) s->opaque; so = (GISTScanOpaque) s->opaque;
if (op == GISTOP_SPLIT) adjuststack(so->s_stack, op, blkno, offnum);
{ adjuststack(so->s_markstk, op, blkno, offnum);
adjuststack(so->s_stack, blkno);
adjuststack(so->s_markstk, blkno);
}
} }
/* /*
@ -405,16 +402,31 @@ adjustiptr(IndexScanDesc s,
* access method update code for heaps; if we've modified the tuple we * access method update code for heaps; if we've modified the tuple we
* are looking at already in this transaction, we ignore the update * are looking at already in this transaction, we ignore the update
* request. * request.
* If index tuple on our parent stack has been deleted, we need
* to make step back to avoid miss.
*/ */
/*ARGSUSED*/
static void static void
adjuststack(GISTSTACK *stk, adjuststack(GISTSTACK *stk, int op, BlockNumber blkno, OffsetNumber offnum)
BlockNumber blkno)
{ {
while (stk != (GISTSTACK *) NULL) while (stk != NULL)
{ {
if (stk->gs_blk == blkno) if (stk->gs_blk == blkno) {
stk->gs_child = FirstOffsetNumber; switch (op) {
case GISTOP_DEL:
if ( stk->gs_child >= offnum ) {
if ( stk->gs_child > FirstOffsetNumber )
stk->gs_child = OffsetNumberPrev( stk->gs_child );
else
stk->gs_child = InvalidOffsetNumber;
}
break;
case GISTOP_SPLIT:
stk->gs_child = InvalidOffsetNumber;
break;
default:
elog(ERROR, "Bad operation in GiST scan adjust: %d", op);
}
}
stk = stk->gs_parent; stk = stk->gs_parent;
} }