]> granicus.if.org Git - postgresql/commitdiff
Fix missing rows in query
authorTeodor Sigaev <teodor@sigaev.ru>
Tue, 30 Aug 2005 08:48:16 +0000 (08:48 +0000)
committerTeodor Sigaev <teodor@sigaev.ru>
Tue, 30 Aug 2005 08:48:16 +0000 (08:48 +0000)
update a=.. where a... with GiST index on column 'a'
Backpatch from 8.0 branch

src/backend/access/gist/gist.c
src/backend/access/gist/gistget.c
src/backend/access/gist/gistscan.c

index c238ea273e56fe443aaf7d03b92a17f4d9c20fea..950d75abd5db9860c8187558ab2bb45f548ba611 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * 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
                 */
                if (ret & SPLITED)
-                       gistadjscans(r, GISTOP_SPLIT, blkno, child);
+                       gistadjscans(r, GISTOP_SPLIT, nblkno, FirstOffsetNumber);
        }
 
        ret = INSERTED;
@@ -1437,6 +1437,9 @@ gistnewroot(Relation r, IndexTuple *itup, int len)
        Page            p;
 
        b = ReadBuffer(r, GISTP_ROOT);
+
+       gistadjscans(r, GISTOP_SPLIT, GISTP_ROOT, FirstOffsetNumber);
+
        GISTInitBuffer(b, 0);
        p = BufferGetPage(b);
 
index 2f5801fe7819fff0e8695f9d786357ebea690595..b10228f18e593e65f453d899462a5ea8b260af1f 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * 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);
                        po = (GISTPageOpaque) PageGetSpecialPointer(p);
 
-                       if (ScanDirectionIsBackward(dir))
-                               n = OffsetNumberPrev(stk->gs_child);
-                       else
-                               n = OffsetNumberNext(stk->gs_child);
+                       if ( stk->gs_child == InvalidOffsetNumber ) { 
+                               /* rescan page */
+                               if (ScanDirectionIsBackward(dir))
+                                       n = PageGetMaxOffsetNumber(p);
+                               else
+                                       n = FirstOffsetNumber;
+                       } else {
+                               if (ScanDirectionIsBackward(dir))
+                                       n = OffsetNumberPrev(stk->gs_child);
+                               else
+                                       n = OffsetNumberNext(stk->gs_child);
+                       }
                        so->s_stack = stk->gs_parent;
                        pfree(stk);
 
index 9c1c92a880aa4e28bf329d73a2a7efe9474ed12a..c8d07916ebd3d92ba2c01449995085ac1b4b2761 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * 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 gistadjone(IndexScanDesc s, int op, BlockNumber blkno,
                   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,
                   int op, BlockNumber blkno, OffsetNumber offnum);
 
@@ -319,11 +319,8 @@ gistadjone(IndexScanDesc s,
 
        so = (GISTScanOpaque) s->opaque;
 
-       if (op == GISTOP_SPLIT)
-       {
-               adjuststack(so->s_stack, blkno);
-               adjuststack(so->s_markstk, blkno);
-       }
+       adjuststack(so->s_stack, op, blkno, offnum);
+       adjuststack(so->s_markstk, op, blkno, offnum);
 }
 
 /*
@@ -405,16 +402,31 @@ adjustiptr(IndexScanDesc s,
  *             access method update code for heaps; if we've modified the tuple we
  *             are looking at already in this transaction, we ignore the update
  *             request.
+ *             If index tuple on our parent stack has been deleted, we need 
+ *             to make step back to avoid miss.
  */
-/*ARGSUSED*/
 static void
-adjuststack(GISTSTACK *stk,
-                       BlockNumber blkno)
+adjuststack(GISTSTACK *stk, int op, BlockNumber blkno, OffsetNumber offnum)
 {
-       while (stk != (GISTSTACK *) NULL)
+       while (stk != NULL)
        {
-               if (stk->gs_blk == blkno)
-                       stk->gs_child = FirstOffsetNumber;
+               if (stk->gs_blk == blkno) {
+                       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;
        }