Patch applied by Neil.  Thanks.

---------------------------------------------------------------------------


Heikki Linnakangas wrote:
> Here's a patch to remove currentItemData & currentMarkpos from 
> IndexScanDesc, and add equivalent fields in access method specific 
> opaque structs for those access methods that need them. That makes the 
> index am API cleaner.
> 
> -- 
>   Heikki Linnakangas
>   EnterpriseDB   http://www.enterprisedb.com
> 

[ text/x-patch is unsupported, treating like TEXT/PLAIN ]

> Index: src/backend/access/gist/gistget.c
> ===================================================================
> RCS file: 
> /home/hlinnaka/pgcvsrepository/pgsql/src/backend/access/gist/gistget.c,v
> retrieving revision 1.60
> diff -c -r1.60 gistget.c
> *** src/backend/access/gist/gistget.c 14 Jul 2006 14:52:16 -0000      1.60
> --- src/backend/access/gist/gistget.c 12 Sep 2006 15:37:48 -0000
> ***************
> *** 106,113 ****
>        * 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));
>   
>       /*
>        * Get the next tuple that matches the search key. If asked to skip 
> killed
> --- 106,113 ----
>        * 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(&(so->curpos)))
> !             killtuple(scan->indexRelation, so, &(so->curpos));
>   
>       /*
>        * Get the next tuple that matches the search key. If asked to skip 
> killed
> ***************
> *** 151,157 ****
>   
>       so = (GISTScanOpaque) scan->opaque;
>   
> !     if (ItemPointerIsValid(&scan->currentItemData) == false)
>       {
>               /* Being asked to fetch the first entry, so start at the root */
>               Assert(so->curbuf == InvalidBuffer);
> --- 151,157 ----
>   
>       so = (GISTScanOpaque) scan->opaque;
>   
> !     if (ItemPointerIsValid(&so->curpos) == false)
>       {
>               /* Being asked to fetch the first entry, so start at the root */
>               Assert(so->curbuf == InvalidBuffer);
> ***************
> *** 226,232 ****
>               }
>   
>               if (!GistPageIsLeaf(p) || resetoffset ||
> !                     !ItemPointerIsValid(&scan->currentItemData))
>               {
>                       if (ScanDirectionIsBackward(dir))
>                               n = PageGetMaxOffsetNumber(p);
> --- 226,232 ----
>               }
>   
>               if (!GistPageIsLeaf(p) || resetoffset ||
> !                     !ItemPointerIsValid(&so->curpos))
>               {
>                       if (ScanDirectionIsBackward(dir))
>                               n = PageGetMaxOffsetNumber(p);
> ***************
> *** 235,241 ****
>               }
>               else
>               {
> !                     n = 
> ItemPointerGetOffsetNumber(&(scan->currentItemData));
>   
>                       if (ScanDirectionIsBackward(dir))
>                               n = OffsetNumberPrev(n);
> --- 235,241 ----
>               }
>               else
>               {
> !                     n = ItemPointerGetOffsetNumber(&(so->curpos));
>   
>                       if (ScanDirectionIsBackward(dir))
>                               n = OffsetNumberPrev(n);
> ***************
> *** 285,291 ****
>                                * we can efficiently resume the index scan 
> later.
>                                */
>   
> !                             ItemPointerSet(&(scan->currentItemData),
>                                                          
> BufferGetBlockNumber(so->curbuf), n);
>   
>                               if (!(ignore_killed_tuples && 
> ItemIdDeleted(PageGetItemId(p, n))))
> --- 285,291 ----
>                                * we can efficiently resume the index scan 
> later.
>                                */
>   
> !                             ItemPointerSet(&(so->curpos),
>                                                          
> BufferGetBlockNumber(so->curbuf), n);
>   
>                               if (!(ignore_killed_tuples && 
> ItemIdDeleted(PageGetItemId(p, n))))
> Index: src/backend/access/gist/gistscan.c
> ===================================================================
> RCS file: 
> /home/hlinnaka/pgcvsrepository/pgsql/src/backend/access/gist/gistscan.c,v
> retrieving revision 1.64
> diff -c -r1.64 gistscan.c
> *** src/backend/access/gist/gistscan.c        14 Jul 2006 14:52:16 -0000      
> 1.64
> --- src/backend/access/gist/gistscan.c        12 Sep 2006 15:38:52 -0000
> ***************
> *** 42,53 ****
>       GISTScanOpaque so;
>       int                     i;
>   
> -     /*
> -      * Clear all the pointers.
> -      */
> -     ItemPointerSetInvalid(&scan->currentItemData);
> -     ItemPointerSetInvalid(&scan->currentMarkData);
> - 
>       so = (GISTScanOpaque) scan->opaque;
>       if (so != NULL)
>       {
> --- 42,47 ----
> ***************
> *** 82,87 ****
> --- 76,88 ----
>               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,117 ****
>                          *n,
>                          *tmp;
>   
> !     scan->currentMarkData = scan->currentItemData;
>       so = (GISTScanOpaque) scan->opaque;
>       if (so->flags & GS_CURBEFORE)
>               so->flags |= GS_MRKBEFORE;
> --- 112,118 ----
>                          *n,
>                          *tmp;
>   
> !     so->markpos = so->curpos;
>       so = (GISTScanOpaque) scan->opaque;
>       if (so->flags & GS_CURBEFORE)
>               so->flags |= GS_MRKBEFORE;
> ***************
> *** 160,166 ****
>                          *n,
>                          *tmp;
>   
> !     scan->currentItemData = scan->currentMarkData;
>       so = (GISTScanOpaque) scan->opaque;
>       if (so->flags & GS_MRKBEFORE)
>               so->flags |= GS_CURBEFORE;
> --- 161,167 ----
>                          *n,
>                          *tmp;
>   
> !     so->curpos = so->markpos;
>       so = (GISTScanOpaque) scan->opaque;
>       if (so->flags & GS_MRKBEFORE)
>               so->flags |= GS_CURBEFORE;
> Index: src/backend/access/hash/hash.c
> ===================================================================
> RCS file: 
> /home/hlinnaka/pgcvsrepository/pgsql/src/backend/access/hash/hash.c,v
> retrieving revision 1.91
> diff -c -r1.91 hash.c
> *** src/backend/access/hash/hash.c    14 Jul 2006 14:52:17 -0000      1.91
> --- src/backend/access/hash/hash.c    12 Sep 2006 15:45:32 -0000
> ***************
> *** 185,191 ****
>        * 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)))
>       {
>               /*
>                * Check to see if we should kill the previously-fetched tuple.
> --- 185,191 ----
>        * appropriate direction.  If we haven't done so yet, we call a routine 
> to
>        * get the first item in the scan.
>        */
> !     if (ItemPointerIsValid(&(so->hashso_curpos)))
>       {
>               /*
>                * Check to see if we should kill the previously-fetched tuple.
> ***************
> *** 195,201 ****
>                       /*
>                        * Yes, so mark it by setting the LP_DELETE bit in the 
> item flags.
>                        */
> !                     offnum = 
> ItemPointerGetOffsetNumber(&(scan->currentItemData));
>                       page = BufferGetPage(so->hashso_curbuf);
>                       PageGetItemId(page, offnum)->lp_flags |= LP_DELETE;
>   
> --- 195,201 ----
>                       /*
>                        * Yes, so mark it by setting the LP_DELETE bit in the 
> item flags.
>                        */
> !                     offnum = 
> ItemPointerGetOffsetNumber(&(so->hashso_curpos));
>                       page = BufferGetPage(so->hashso_curbuf);
>                       PageGetItemId(page, offnum)->lp_flags |= LP_DELETE;
>   
> ***************
> *** 222,228 ****
>       {
>               while (res)
>               {
> !                     offnum = 
> ItemPointerGetOffsetNumber(&(scan->currentItemData));
>                       page = BufferGetPage(so->hashso_curbuf);
>                       if (!ItemIdDeleted(PageGetItemId(page, offnum)))
>                               break;
> --- 222,228 ----
>       {
>               while (res)
>               {
> !                     offnum = 
> ItemPointerGetOffsetNumber(&(so->hashso_curpos));
>                       page = BufferGetPage(so->hashso_curbuf);
>                       if (!ItemIdDeleted(PageGetItemId(page, offnum)))
>                               break;
> ***************
> *** 269,275 ****
>               /*
>                * Start scan, or advance to next tuple.
>                */
> !             if (ItemPointerIsValid(&(scan->currentItemData)))
>                       res = _hash_next(scan, ForwardScanDirection);
>               else
>                       res = _hash_first(scan, ForwardScanDirection);
> --- 269,275 ----
>               /*
>                * Start scan, or advance to next tuple.
>                */
> !             if (ItemPointerIsValid(&(so->hashso_curpos)))
>                       res = _hash_next(scan, ForwardScanDirection);
>               else
>                       res = _hash_first(scan, ForwardScanDirection);
> ***************
> *** 284,290 ****
>                               Page            page;
>                               OffsetNumber offnum;
>   
> !                             offnum = 
> ItemPointerGetOffsetNumber(&(scan->currentItemData));
>                               page = BufferGetPage(so->hashso_curbuf);
>                               if (!ItemIdDeleted(PageGetItemId(page, offnum)))
>                                       break;
> --- 284,290 ----
>                               Page            page;
>                               OffsetNumber offnum;
>   
> !                             offnum = 
> ItemPointerGetOffsetNumber(&(so->hashso_curpos));
>                               page = BufferGetPage(so->hashso_curbuf);
>                               if (!ItemIdDeleted(PageGetItemId(page, offnum)))
>                                       break;
> ***************
> *** 326,331 ****
> --- 326,335 ----
>       so->hashso_bucket_blkno = 0;
>       so->hashso_curbuf = so->hashso_mrkbuf = InvalidBuffer;
>       scan->opaque = so;
> +     /* set positions invalid (this will cause _hash_first call) */
> +     ItemPointerSetInvalid(&(so->hashso_curpos));
> +     ItemPointerSetInvalid(&(so->hashso_mrkpos));
> + 
>   
>       /* register scan in case we change pages it's using */
>       _hash_regscan(scan);
> ***************
> *** 360,370 ****
>               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));
>   
>       /* Update scan key, if a new one is given */
>       if (scankey && scan->numberOfKeys > 0)
> --- 364,374 ----
>               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(&(so->hashso_curpos));
> !             ItemPointerSetInvalid(&(so->hashso_mrkpos));
> !     }
>   
>       /* Update scan key, if a new one is given */
>       if (scankey && scan->numberOfKeys > 0)
> ***************
> *** 406,415 ****
>               _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;
>   
> --- 410,415 ----
> ***************
> *** 430,443 ****
>       if (BufferIsValid(so->hashso_mrkbuf))
>               _hash_dropbuf(rel, so->hashso_mrkbuf);
>       so->hashso_mrkbuf = InvalidBuffer;
> !     ItemPointerSetInvalid(&(scan->currentMarkData));
>   
> !     /* bump pin count on currentItemData and copy to currentMarkData */
> !     if (ItemPointerIsValid(&(scan->currentItemData)))
>       {
>               IncrBufferRefCount(so->hashso_curbuf);
>               so->hashso_mrkbuf = so->hashso_curbuf;
> !             scan->currentMarkData = scan->currentItemData;
>       }
>   
>       PG_RETURN_VOID();
> --- 430,443 ----
>       if (BufferIsValid(so->hashso_mrkbuf))
>               _hash_dropbuf(rel, so->hashso_mrkbuf);
>       so->hashso_mrkbuf = InvalidBuffer;
> !     ItemPointerSetInvalid(&(so->hashso_mrkpos));
>   
> !     /* 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;
> !             so->hashso_mrkpos = so->hashso_curpos;
>       }
>   
>       PG_RETURN_VOID();
> ***************
> *** 457,470 ****
>       if (BufferIsValid(so->hashso_curbuf))
>               _hash_dropbuf(rel, so->hashso_curbuf);
>       so->hashso_curbuf = InvalidBuffer;
> !     ItemPointerSetInvalid(&(scan->currentItemData));
>   
> !     /* bump pin count on currentMarkData and copy to currentItemData */
> !     if (ItemPointerIsValid(&(scan->currentMarkData)))
>       {
>               IncrBufferRefCount(so->hashso_mrkbuf);
>               so->hashso_curbuf = so->hashso_mrkbuf;
> !             scan->currentItemData = scan->currentMarkData;
>       }
>   
>       PG_RETURN_VOID();
> --- 457,470 ----
>       if (BufferIsValid(so->hashso_curbuf))
>               _hash_dropbuf(rel, so->hashso_curbuf);
>       so->hashso_curbuf = InvalidBuffer;
> !     ItemPointerSetInvalid(&(so->hashso_curpos));
>   
> !     /* 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;
> !             so->hashso_curpos = so->hashso_mrkpos;
>       }
>   
>       PG_RETURN_VOID();
> Index: src/backend/access/hash/hashsearch.c
> ===================================================================
> RCS file: 
> /home/hlinnaka/pgcvsrepository/pgsql/src/backend/access/hash/hashsearch.c,v
> retrieving revision 1.45
> diff -c -r1.45 hashsearch.c
> *** src/backend/access/hash/hashsearch.c      14 Jul 2006 14:52:17 -0000      
> 1.45
> --- src/backend/access/hash/hashsearch.c      12 Sep 2006 15:44:45 -0000
> ***************
> *** 21,27 ****
>   /*
>    *  _hash_next() -- Get the next item in a scan.
>    *
> !  *          On entry, we have a valid currentItemData 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
> --- 21,27 ----
>   /*
>    *  _hash_next() -- Get the next item in a scan.
>    *
> !  *          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,55 ****
>               return false;
>   
>       /* if we're here, _hash_step found a valid tuple */
> !     current = &(scan->currentItemData);
>       offnum = ItemPointerGetOffsetNumber(current);
>       _hash_checkpage(rel, buf, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
>       page = BufferGetPage(buf);
> --- 49,55 ----
>               return false;
>   
>       /* if we're here, _hash_step found a valid tuple */
> !     current = &(so->hashso_curpos);
>       offnum = ItemPointerGetOffsetNumber(current);
>       _hash_checkpage(rel, buf, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
>       page = BufferGetPage(buf);
> ***************
> *** 129,135 ****
>   
>       pgstat_count_index_scan(&scan->xs_pgstat_info);
>   
> !     current = &(scan->currentItemData);
>       ItemPointerSetInvalid(current);
>   
>       /*
> --- 129,135 ----
>   
>       pgstat_count_index_scan(&scan->xs_pgstat_info);
>   
> !     current = &(so->hashso_curpos);
>       ItemPointerSetInvalid(current);
>   
>       /*
> ***************
> *** 224,230 ****
>    *  _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
>    *          scan to the right thing.
>    *
>    *          'bufP' points to the current buffer, which is pinned and 
> read-locked.
> --- 224,230 ----
>    *  _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 hashso_curpos for the
>    *          scan to the right thing.
>    *
>    *          'bufP' points to the current buffer, which is pinned and 
> read-locked.
> ***************
> *** 245,251 ****
>       BlockNumber blkno;
>       IndexTuple      itup;
>   
> !     current = &(scan->currentItemData);
>   
>       buf = *bufP;
>       _hash_checkpage(rel, buf, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
> --- 245,251 ----
>       BlockNumber blkno;
>       IndexTuple      itup;
>   
> !     current = &(so->hashso_curpos);
>   
>       buf = *bufP;
>       _hash_checkpage(rel, buf, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
> Index: src/backend/access/index/genam.c
> ===================================================================
> RCS file: 
> /home/hlinnaka/pgcvsrepository/pgsql/src/backend/access/index/genam.c,v
> retrieving revision 1.58
> diff -c -r1.58 genam.c
> *** src/backend/access/index/genam.c  31 Jul 2006 20:08:59 -0000      1.58
> --- src/backend/access/index/genam.c  12 Sep 2006 15:45:54 -0000
> ***************
> *** 92,100 ****
>   
>       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;
> --- 92,97 ----
> Index: src/include/access/gist_private.h
> ===================================================================
> RCS file: 
> /home/hlinnaka/pgcvsrepository/pgsql/src/include/access/gist_private.h,v
> retrieving revision 1.23
> diff -c -r1.23 gist_private.h
> *** src/include/access/gist_private.h 7 Aug 2006 16:57:57 -0000       1.23
> --- src/include/access/gist_private.h 12 Sep 2006 15:36:30 -0000
> ***************
> *** 72,78 ****
> --- 72,80 ----
>       GISTSTATE  *giststate;
>       MemoryContext tempCxt;
>       Buffer          curbuf;
> +     ItemPointerData curpos;
>       Buffer          markbuf;
> +     ItemPointerData markpos;
>   } GISTScanOpaqueData;
>   
>   typedef GISTScanOpaqueData *GISTScanOpaque;
> Index: src/include/access/hash.h
> ===================================================================
> RCS file: /home/hlinnaka/pgcvsrepository/pgsql/src/include/access/hash.h,v
> retrieving revision 1.73
> diff -c -r1.73 hash.h
> *** src/include/access/hash.h 13 Jul 2006 16:49:19 -0000      1.73
> --- src/include/access/hash.h 12 Sep 2006 15:39:28 -0000
> ***************
> *** 97,102 ****
> --- 97,106 ----
>        */
>       Buffer          hashso_curbuf;
>       Buffer          hashso_mrkbuf;
> + 
> +     /* Current and marked position of the scan */
> +     ItemPointerData hashso_curpos;
> +     ItemPointerData hashso_mrkpos;
>   } HashScanOpaqueData;
>   
>   typedef HashScanOpaqueData *HashScanOpaque;
> Index: src/include/access/nbtree.h
> ===================================================================
> RCS file: /home/hlinnaka/pgcvsrepository/pgsql/src/include/access/nbtree.h,v
> retrieving revision 1.104
> diff -c -r1.104 nbtree.h
> *** src/include/access/nbtree.h       24 Aug 2006 01:18:34 -0000      1.104
> --- src/include/access/nbtree.h       12 Sep 2006 15:55:17 -0000
> ***************
> *** 383,391 ****
>    * 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 */
> --- 383,388 ----
> Index: src/include/access/relscan.h
> ===================================================================
> RCS file: /home/hlinnaka/pgcvsrepository/pgsql/src/include/access/relscan.h,v
> retrieving revision 1.49
> diff -c -r1.49 relscan.h
> *** src/include/access/relscan.h      31 Jul 2006 20:09:05 -0000      1.49
> --- src/include/access/relscan.h      12 Sep 2006 15:52:50 -0000
> ***************
> *** 69,77 ****
>   
>       /* 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
> --- 69,74 ----

> 
> ---------------------------(end of broadcast)---------------------------
> TIP 1: if posting/reading through Usenet, please send an appropriate
>        subscribe-nomail command to [EMAIL PROTECTED] so that your
>        message can get through to the mailing list cleanly

-- 
  Bruce Momjian   [EMAIL PROTECTED]
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
       subscribe-nomail command to [EMAIL PROTECTED] so that your
       message can get through to the mailing list cleanly

Reply via email to