OSDN Git Service

Refactor the index AM API slightly: move currentItemData and
authorNeil Conway <neilc@samurai.com>
Sat, 20 Jan 2007 18:43:35 +0000 (18:43 +0000)
committerNeil Conway <neilc@samurai.com>
Sat, 20 Jan 2007 18:43:35 +0000 (18:43 +0000)
currentMarkData from IndexScanDesc to the opaque structs for the
AMs that need this information (currently gist and hash).

Patch from Heikki Linnakangas, fixes by Neil Conway.

src/backend/access/gist/gistget.c
src/backend/access/gist/gistscan.c
src/backend/access/hash/hash.c
src/backend/access/hash/hashsearch.c
src/backend/access/index/genam.c
src/include/access/gist_private.h
src/include/access/hash.h
src/include/access/nbtree.h
src/include/access/relscan.h

index f36653b..f1d2c77 100644 (file)
@@ -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.63 2007/01/05 22:19:22 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.64 2007/01/20 18:43:35 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -106,8 +106,8 @@ gistgettuple(PG_FUNCTION_ARGS)
         * If we have produced an index tuple in the past and the executor has
         * informed us we need to mark it as "killed", do so now.
         */
-       if (scan->kill_prior_tuple && ItemPointerIsValid(&(scan->currentItemData)))
-               killtuple(scan->indexRelation, so, &(scan->currentItemData));
+       if (scan->kill_prior_tuple && ItemPointerIsValid(&(so->curpos)))
+               killtuple(scan->indexRelation, so, &(so->curpos));
 
        /*
         * Get the next tuple that matches the search key. If asked to skip killed
@@ -138,7 +138,8 @@ gistgetmulti(PG_FUNCTION_ARGS)
  * tuples. Returns true iff a matching tuple was found.
  */
 static int
-gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, bool ignore_killed_tuples)
+gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids,
+                int maxtids, bool ignore_killed_tuples)
 {
        Page            p;
        OffsetNumber n;
@@ -151,7 +152,7 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
 
        so = (GISTScanOpaque) scan->opaque;
 
-       if (ItemPointerIsValid(&scan->currentItemData) == false)
+       if (ItemPointerIsValid(&so->curpos) == false)
        {
                /* Being asked to fetch the first entry, so start at the root */
                Assert(so->curbuf == InvalidBuffer);
@@ -226,7 +227,7 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
                }
 
                if (!GistPageIsLeaf(p) || resetoffset ||
-                       !ItemPointerIsValid(&scan->currentItemData))
+                       !ItemPointerIsValid(&so->curpos))
                {
                        if (ScanDirectionIsBackward(dir))
                                n = PageGetMaxOffsetNumber(p);
@@ -235,7 +236,7 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
                }
                else
                {
-                       n = ItemPointerGetOffsetNumber(&(scan->currentItemData));
+                       n = ItemPointerGetOffsetNumber(&(so->curpos));
 
                        if (ScanDirectionIsBackward(dir))
                                n = OffsetNumberPrev(n);
@@ -285,7 +286,7 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
                                 * we can efficiently resume the index scan later.
                                 */
 
-                               ItemPointerSet(&(scan->currentItemData),
+                               ItemPointerSet(&(so->curpos),
                                                           BufferGetBlockNumber(so->curbuf), n);
 
                                if (!(ignore_killed_tuples && ItemIdDeleted(PageGetItemId(p, n))))
index 08ca733..a275bb2 100644 (file)
@@ -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.66 2007/01/05 22:19:22 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.67 2007/01/20 18:43:35 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -42,12 +42,6 @@ gistrescan(PG_FUNCTION_ARGS)
        GISTScanOpaque so;
        int                     i;
 
-       /*
-        * Clear all the pointers.
-        */
-       ItemPointerSetInvalid(&scan->currentItemData);
-       ItemPointerSetInvalid(&scan->currentMarkData);
-
        so = (GISTScanOpaque) scan->opaque;
        if (so != NULL)
        {
@@ -82,6 +76,12 @@ gistrescan(PG_FUNCTION_ARGS)
                scan->opaque = so;
        }
 
+       /*
+        * Clear all the pointers.
+        */
+       ItemPointerSetInvalid(&so->curpos);
+       ItemPointerSetInvalid(&so->markpos);
+
        /* Update scan key, if a new one is given */
        if (key && scan->numberOfKeys > 0)
        {
@@ -111,8 +111,8 @@ gistmarkpos(PG_FUNCTION_ARGS)
                           *n,
                           *tmp;
 
-       scan->currentMarkData = scan->currentItemData;
        so = (GISTScanOpaque) scan->opaque;
+       so->markpos = so->curpos;
        if (so->flags & GS_CURBEFORE)
                so->flags |= GS_MRKBEFORE;
        else
@@ -160,8 +160,8 @@ gistrestrpos(PG_FUNCTION_ARGS)
                           *n,
                           *tmp;
 
-       scan->currentItemData = scan->currentMarkData;
        so = (GISTScanOpaque) scan->opaque;
+       so->curpos = so->markpos;
        if (so->flags & GS_MRKBEFORE)
                so->flags |= GS_CURBEFORE;
        else
index aa64c1d..6a5eb37 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.92 2007/01/05 22:19:22 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.93 2007/01/20 18:43:35 neilc Exp $
  *
  * NOTES
  *       This file contains only the public interface routines.
@@ -185,7 +185,7 @@ hashgettuple(PG_FUNCTION_ARGS)
         * appropriate direction.  If we haven't done so yet, we call a routine to
         * get the first item in the scan.
         */
-       if (ItemPointerIsValid(&(scan->currentItemData)))
+       if (ItemPointerIsValid(&(so->hashso_curpos)))
        {
                /*
                 * Check to see if we should kill the previously-fetched tuple.
@@ -195,7 +195,7 @@ hashgettuple(PG_FUNCTION_ARGS)
                        /*
                         * Yes, so mark it by setting the LP_DELETE bit in the item flags.
                         */
-                       offnum = ItemPointerGetOffsetNumber(&(scan->currentItemData));
+                       offnum = ItemPointerGetOffsetNumber(&(so->hashso_curpos));
                        page = BufferGetPage(so->hashso_curbuf);
                        PageGetItemId(page, offnum)->lp_flags |= LP_DELETE;
 
@@ -222,7 +222,7 @@ hashgettuple(PG_FUNCTION_ARGS)
        {
                while (res)
                {
-                       offnum = ItemPointerGetOffsetNumber(&(scan->currentItemData));
+                       offnum = ItemPointerGetOffsetNumber(&(so->hashso_curpos));
                        page = BufferGetPage(so->hashso_curbuf);
                        if (!ItemIdDeleted(PageGetItemId(page, offnum)))
                                break;
@@ -269,7 +269,7 @@ hashgetmulti(PG_FUNCTION_ARGS)
                /*
                 * Start scan, or advance to next tuple.
                 */
-               if (ItemPointerIsValid(&(scan->currentItemData)))
+               if (ItemPointerIsValid(&(so->hashso_curpos)))
                        res = _hash_next(scan, ForwardScanDirection);
                else
                        res = _hash_first(scan, ForwardScanDirection);
@@ -284,7 +284,7 @@ hashgetmulti(PG_FUNCTION_ARGS)
                                Page            page;
                                OffsetNumber offnum;
 
-                               offnum = ItemPointerGetOffsetNumber(&(scan->currentItemData));
+                               offnum = ItemPointerGetOffsetNumber(&(so->hashso_curpos));
                                page = BufferGetPage(so->hashso_curbuf);
                                if (!ItemIdDeleted(PageGetItemId(page, offnum)))
                                        break;
@@ -325,6 +325,10 @@ hashbeginscan(PG_FUNCTION_ARGS)
        so->hashso_bucket_valid = false;
        so->hashso_bucket_blkno = 0;
        so->hashso_curbuf = so->hashso_mrkbuf = InvalidBuffer;
+       /* set positions invalid (this will cause _hash_first call) */
+       ItemPointerSetInvalid(&(so->hashso_curpos));
+       ItemPointerSetInvalid(&(so->hashso_mrkpos));
+
        scan->opaque = so;
 
        /* register scan in case we change pages it's using */
@@ -360,11 +364,11 @@ hashrescan(PG_FUNCTION_ARGS)
                if (so->hashso_bucket_blkno)
                        _hash_droplock(rel, so->hashso_bucket_blkno, HASH_SHARE);
                so->hashso_bucket_blkno = 0;
-       }
 
-       /* set positions invalid (this will cause _hash_first call) */
-       ItemPointerSetInvalid(&(scan->currentItemData));
-       ItemPointerSetInvalid(&(scan->currentMarkData));
+               /* set positions invalid (this will cause _hash_first call) */
+               ItemPointerSetInvalid(&(so->hashso_curpos));
+               ItemPointerSetInvalid(&(so->hashso_mrkpos));
+       }
 
        /* Update scan key, if a new one is given */
        if (scankey && scan->numberOfKeys > 0)
@@ -406,10 +410,6 @@ hashendscan(PG_FUNCTION_ARGS)
                _hash_droplock(rel, so->hashso_bucket_blkno, HASH_SHARE);
        so->hashso_bucket_blkno = 0;
 
-       /* be tidy */
-       ItemPointerSetInvalid(&(scan->currentItemData));
-       ItemPointerSetInvalid(&(scan->currentMarkData));
-
        pfree(so);
        scan->opaque = NULL;
 
@@ -430,14 +430,14 @@ hashmarkpos(PG_FUNCTION_ARGS)
        if (BufferIsValid(so->hashso_mrkbuf))
                _hash_dropbuf(rel, so->hashso_mrkbuf);
        so->hashso_mrkbuf = InvalidBuffer;
-       ItemPointerSetInvalid(&(scan->currentMarkData));
+       ItemPointerSetInvalid(&(so->hashso_mrkpos));
 
-       /* bump pin count on currentItemData and copy to currentMarkData */
-       if (ItemPointerIsValid(&(scan->currentItemData)))
+       /* bump pin count on current buffer and copy to marked buffer */
+       if (ItemPointerIsValid(&(so->hashso_curpos)))
        {
                IncrBufferRefCount(so->hashso_curbuf);
                so->hashso_mrkbuf = so->hashso_curbuf;
-               scan->currentMarkData = scan->currentItemData;
+               so->hashso_mrkpos = so->hashso_curpos;
        }
 
        PG_RETURN_VOID();
@@ -457,14 +457,14 @@ hashrestrpos(PG_FUNCTION_ARGS)
        if (BufferIsValid(so->hashso_curbuf))
                _hash_dropbuf(rel, so->hashso_curbuf);
        so->hashso_curbuf = InvalidBuffer;
-       ItemPointerSetInvalid(&(scan->currentItemData));
+       ItemPointerSetInvalid(&(so->hashso_curpos));
 
-       /* bump pin count on currentMarkData and copy to currentItemData */
-       if (ItemPointerIsValid(&(scan->currentMarkData)))
+       /* bump pin count on marked buffer and copy to current buffer */
+       if (ItemPointerIsValid(&(so->hashso_mrkpos)))
        {
                IncrBufferRefCount(so->hashso_mrkbuf);
                so->hashso_curbuf = so->hashso_mrkbuf;
-               scan->currentItemData = scan->currentMarkData;
+               so->hashso_curpos = so->hashso_mrkpos;
        }
 
        PG_RETURN_VOID();
index 29b2ea5..5582c03 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/hash/hashsearch.c,v 1.46 2007/01/05 22:19:22 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/hash/hashsearch.c,v 1.47 2007/01/20 18:43:35 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,7 +21,7 @@
 /*
  *     _hash_next() -- Get the next item in a scan.
  *
- *             On entry, we have a valid currentItemData in the scan, and a
+ *             On entry, we have a valid hashso_curpos in the scan, and a
  *             pin and read lock on the page that contains that item.
  *             We find the next item in the scan, if any.
  *             On success exit, we have the page containing the next item
@@ -49,7 +49,7 @@ _hash_next(IndexScanDesc scan, ScanDirection dir)
                return false;
 
        /* if we're here, _hash_step found a valid tuple */
-       current = &(scan->currentItemData);
+       current = &(so->hashso_curpos);
        offnum = ItemPointerGetOffsetNumber(current);
        _hash_checkpage(rel, buf, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
        page = BufferGetPage(buf);
@@ -129,7 +129,7 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
 
        pgstat_count_index_scan(&scan->xs_pgstat_info);
 
-       current = &(scan->currentItemData);
+       current = &(so->hashso_curpos);
        ItemPointerSetInvalid(current);
 
        /*
@@ -224,7 +224,7 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
  *     _hash_step() -- step to the next valid item in a scan in the bucket.
  *
  *             If no valid record exists in the requested direction, return
- *             false.  Else, return true and set the CurrentItemData for the
+ *             false.  Else, return true and set the hashso_curpos for the
  *             scan to the right thing.
  *
  *             'bufP' points to the current buffer, which is pinned and read-locked.
@@ -245,7 +245,7 @@ _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir)
        BlockNumber blkno;
        IndexTuple      itup;
 
-       current = &(scan->currentItemData);
+       current = &(so->hashso_curpos);
 
        buf = *bufP;
        _hash_checkpage(rel, buf, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
index d0db99a..49ffff6 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.60 2007/01/05 22:19:22 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.61 2007/01/20 18:43:35 neilc Exp $
  *
  * NOTES
  *       many of the old access method routines have been turned into
@@ -92,9 +92,6 @@ RelationGetIndexScan(Relation indexRelation,
 
        scan->opaque = NULL;
 
-       ItemPointerSetInvalid(&scan->currentItemData);
-       ItemPointerSetInvalid(&scan->currentMarkData);
-
        ItemPointerSetInvalid(&scan->xs_ctup.t_self);
        scan->xs_ctup.t_data = NULL;
        scan->xs_cbuf = InvalidBuffer;
index 25d2c21..6cb2e52 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.25 2007/01/05 22:19:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.26 2007/01/20 18:43:35 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -72,7 +72,9 @@ typedef struct GISTScanOpaqueData
        GISTSTATE  *giststate;
        MemoryContext tempCxt;
        Buffer          curbuf;
+       ItemPointerData curpos;
        Buffer          markbuf;
+       ItemPointerData markpos;
 } GISTScanOpaqueData;
 
 typedef GISTScanOpaqueData *GISTScanOpaque;
index 0a88b92..40c86b7 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/hash.h,v 1.74 2007/01/05 22:19:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/hash.h,v 1.75 2007/01/20 18:43:35 neilc Exp $
  *
  * NOTES
  *             modeled after Margo Seltzer's hash implementation for unix.
@@ -97,6 +97,10 @@ typedef struct HashScanOpaqueData
         */
        Buffer          hashso_curbuf;
        Buffer          hashso_mrkbuf;
+
+       /* Current and marked position of the scan */
+       ItemPointerData hashso_curpos;
+       ItemPointerData hashso_mrkpos;
 } HashScanOpaqueData;
 
 typedef HashScanOpaqueData *HashScanOpaque;
index 435826c..574aec4 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.108 2007/01/09 02:14:15 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.109 2007/01/20 18:43:35 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -390,9 +390,6 @@ typedef BTStackData *BTStack;
  * items were killed, we re-lock the page to mark them killed, then unlock.
  * Finally we drop the pin and step to the next page in the appropriate
  * direction.
- *
- * NOTE: in this implementation, btree does not use or set the
- * currentItemData and currentMarkData fields of IndexScanDesc at all.
  */
 
 typedef struct BTScanPosItem   /* what we remember about each match */
index bd1a9a4..77bca6b 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.51 2007/01/05 22:19:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.52 2007/01/20 18:43:35 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -69,9 +69,6 @@ typedef struct IndexScanDescData
 
        /* index access method's private state */
        void       *opaque;                     /* access-method-specific info */
-       /* these fields are used by some but not all AMs: */
-       ItemPointerData currentItemData;        /* current index pointer */
-       ItemPointerData currentMarkData;        /* marked position, if any */
 
        /*
         * xs_ctup/xs_cbuf are valid after a successful index_getnext. After