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 f36653babdf12673e5898ba6cd24a353ab10e948..f1d2c777c2f98de15cdd0ffac3b2afc20555621f 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 08ca73357c008b5b9111cd9bba7331ec2d7d3c57..a275bb257ce3fa1372df0e41c993eaccb64e734e 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 aa64c1d88bd8fa08b60e19bc3807e791cb0b71b0..6a5eb37592d7967a44b0bb44a9f8e381d102994b 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 29b2ea545ab51f48d8141ea3430c4444bfbfd56c..5582c03641737ba549198f6cd59f022bf98fb77b 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 d0db99af75db6a28392af2f7cc40c06508f40751..49ffff6e51db8a8f87f4fbdb01d2da29a9638663 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 25d2c213c00f15ccc6e94faf10f9f5c8b8f65368..6cb2e5294e559e4c2d868d92fc040bfe03a74f3b 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 0a88b9203f63d6c202235fe9b27ad20880b78a9c..40c86b745520247607b2bd0240a57a62c447551e 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 435826cf457ef61fc3ddb3d574bde04c71220423..574aec496f8c0d56f1bea005d4b1ff86408407f6 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 bd1a9a4c3f83496b45bf38245fd3d73b2630645d..77bca6be482b8e5c4025476b55a048406cd08d93 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