]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Adjust amrescan code so that it's allowed to call index_rescan with a
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 23 Mar 2003 23:01:03 +0000 (23:01 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 23 Mar 2003 23:01:03 +0000 (23:01 +0000)
NULL key pointer, indicating that the existing scan key should be reused.
This behavior isn't used yet but will be needed for my planned fix to
the keys_are_unique code.

src/backend/access/gist/gistscan.c
src/backend/access/hash/hash.c
src/backend/access/index/indexam.c
src/backend/access/nbtree/nbtree.c
src/backend/access/rtree/rtscan.c

index 9c1c92a880aa4e28bf329d73a2a7efe9474ed12a..8a23b9b115cd5cb4f506c87a7a660360a27bd398 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.44 2003/03/23 23:01:02 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -78,28 +78,14 @@ gistrescan(PG_FUNCTION_ARGS)
        ItemPointerSetInvalid(&s->currentItemData);
        ItemPointerSetInvalid(&s->currentMarkData);
 
-       if (s->numberOfKeys > 0)
-       {
-               memmove(s->keyData,
-                               key,
-                               s->numberOfKeys * sizeof(ScanKeyData));
-       }
-
        p = (GISTScanOpaque) s->opaque;
        if (p != (GISTScanOpaque) NULL)
        {
+               /* rescan an existing indexscan --- reset state */
                gistfreestack(p->s_stack);
                gistfreestack(p->s_markstk);
                p->s_stack = p->s_markstk = (GISTSTACK *) NULL;
                p->s_flags = 0x0;
-               for (i = 0; i < s->numberOfKeys; i++)
-               {
-                       s->keyData[i].sk_procedure
-                               = RelationGetGISTStrategy(s->indexRelation,
-                                                                                 s->keyData[i].sk_attno,
-                                                                                 s->keyData[i].sk_procedure);
-                       s->keyData[i].sk_func = p->giststate->consistentFn[s->keyData[i].sk_attno - 1];
-               }
        }
        else
        {
@@ -110,22 +96,28 @@ gistrescan(PG_FUNCTION_ARGS)
                s->opaque = p;
                p->giststate = (GISTSTATE *) palloc(sizeof(GISTSTATE));
                initGISTstate(p->giststate, s->indexRelation);
-               if (s->numberOfKeys > 0)
-
-                       /*
-                        * * Play games here with the scan key to use the Consistent *
-                        * function for all comparisons: * 1) the sk_procedure field
-                        * will now be used to hold the *        strategy number * 2) the
-                        * sk_func field will point to the Consistent function
-                        */
-                       for (i = 0; i < s->numberOfKeys; i++)
-                       {
-                               s->keyData[i].sk_procedure =
-                                       RelationGetGISTStrategy(s->indexRelation,
-                                                                                       s->keyData[i].sk_attno,
-                                                                                       s->keyData[i].sk_procedure);
-                               s->keyData[i].sk_func = p->giststate->consistentFn[s->keyData[i].sk_attno - 1];
-                       }
+       }
+
+       /* Update scan key, if a new one is given */
+       if (key && s->numberOfKeys > 0)
+       {
+               memmove(s->keyData,
+                               key,
+                               s->numberOfKeys * sizeof(ScanKeyData));
+               /*
+                * Play games here with the scan key to use the Consistent
+                * function for all comparisons: 1) the sk_procedure field
+                * will now be used to hold the strategy number 2) the
+                * sk_func field will point to the Consistent function
+                */
+               for (i = 0; i < s->numberOfKeys; i++)
+               {
+                       s->keyData[i].sk_procedure =
+                               RelationGetGISTStrategy(s->indexRelation,
+                                                                               s->keyData[i].sk_attno,
+                                                                               s->keyData[i].sk_procedure);
+                       s->keyData[i].sk_func = p->giststate->consistentFn[s->keyData[i].sk_attno - 1];
+               }
        }
 
        PG_RETURN_VOID();
index 705041f7d274e8e6ae4e6708d252b81763ae70d6..f3534d2e174144d847160ff95076f37516436ac9 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.62 2003/02/24 00:57:17 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.63 2003/03/23 23:01:03 tgl Exp $
  *
  * NOTES
  *       This file contains only the public interface routines.
@@ -302,10 +302,8 @@ hashrescan(PG_FUNCTION_ARGS)
 {
        IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
        ScanKey         scankey = (ScanKey) PG_GETARG_POINTER(1);
+       HashScanOpaque so = (HashScanOpaque) scan->opaque;
        ItemPointer iptr;
-       HashScanOpaque so;
-
-       so = (HashScanOpaque) scan->opaque;
 
        /* we hold a read lock on the current page in the scan */
        if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
@@ -321,8 +319,8 @@ hashrescan(PG_FUNCTION_ARGS)
                ItemPointerSetInvalid(iptr);
        }
 
-       /* reset the scan key */
-       if (scan->numberOfKeys > 0)
+       /* Update scan key, if a new one is given */
+       if (scankey && scan->numberOfKeys > 0)
        {
                memmove(scan->keyData,
                                scankey,
index d045bafc1c86eaf2a1c235fd7fcb877e30673e87..2f0c6aac529f585af8a649903f4e18e04b0aeb72 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.64 2003/02/22 00:45:03 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.65 2003/03/23 23:01:03 tgl Exp $
  *
  * INTERFACE ROUTINES
  *             index_open              - open an index relation by relation OID
@@ -294,8 +294,12 @@ index_beginscan(Relation heapRelation,
  *             index_rescan  - (re)start a scan of an index
  *
  * The caller may specify a new set of scankeys (but the number of keys
- * cannot change).     Note that this is also called when first starting
- * an indexscan; see RelationGetIndexScan.
+ * cannot change).  To restart the scan without changing keys, pass NULL
+ * for the key array.
+ *
+ * Note that this is also called when first starting an indexscan;
+ * see RelationGetIndexScan.  Keys *must* be passed in that case,
+ * unless scan->numberOfKeys is zero.
  * ----------------
  */
 void
index b1722244e6d9e7d78f0b6ef961adf0cf5e79f53d..a35901b47c6bfefa37fa9df63f1a6bec04bb122f 100644 (file)
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.101 2003/03/04 21:51:20 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.102 2003/03/23 23:01:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -396,6 +396,7 @@ btrescan(PG_FUNCTION_ARGS)
                        so->keyData = (ScanKey) palloc(scan->numberOfKeys * sizeof(ScanKeyData));
                else
                        so->keyData = (ScanKey) NULL;
+               so->numberOfKeys = scan->numberOfKeys;
                scan->opaque = so;
        }
 
@@ -420,12 +421,12 @@ btrescan(PG_FUNCTION_ARGS)
         * Reset the scan keys. Note that keys ordering stuff moved to
         * _bt_first.      - vadim 05/05/97
         */
-       so->numberOfKeys = scan->numberOfKeys;
-       if (scan->numberOfKeys > 0)
+       if (scankey && scan->numberOfKeys > 0)
        {
                memmove(scan->keyData,
                                scankey,
                                scan->numberOfKeys * sizeof(ScanKeyData));
+               so->numberOfKeys = scan->numberOfKeys;
                memmove(so->keyData,
                                scankey,
                                so->numberOfKeys * sizeof(ScanKeyData));
index 52aedeae2b8882ed5ba05c91d0143f9a53c813b4..a0b9883cfe80db31b290292bbf8d55928edec9e7 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.42 2002/06/20 20:29:25 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.43 2003/03/23 23:01:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -80,22 +80,14 @@ rtrescan(PG_FUNCTION_ARGS)
        ItemPointerSetInvalid(&s->currentItemData);
        ItemPointerSetInvalid(&s->currentMarkData);
 
-       if (s->numberOfKeys > 0)
-       {
-               memmove(s->keyData,
-                               key,
-                               s->numberOfKeys * sizeof(ScanKeyData));
-       }
-
        p = (RTreeScanOpaque) s->opaque;
        if (p != (RTreeScanOpaque) NULL)
        {
+               /* rescan an existing indexscan --- reset state */
                freestack(p->s_stack);
                freestack(p->s_markstk);
                p->s_stack = p->s_markstk = (RTSTACK *) NULL;
                p->s_flags = 0x0;
-               for (i = 0; i < s->numberOfKeys; i++)
-                       p->s_internalKey[i].sk_argument = s->keyData[i].sk_argument;
        }
        else
        {
@@ -106,28 +98,32 @@ rtrescan(PG_FUNCTION_ARGS)
                p->s_flags = 0x0;
                s->opaque = p;
                if (s->numberOfKeys > 0)
-               {
                        p->s_internalKey = (ScanKey) palloc(sizeof(ScanKeyData) * s->numberOfKeys);
+       }
 
-                       /*
-                        * Scans on internal pages use different operators than they
-                        * do on leaf pages.  For example, if the user wants all boxes
-                        * that exactly match (x1,y1,x2,y2), then on internal pages we
-                        * need to find all boxes that contain (x1,y1,x2,y2).
-                        */
+       /* Update scan key, if a new one is given */
+       if (key && s->numberOfKeys > 0)
+       {
+               memmove(s->keyData,
+                               key,
+                               s->numberOfKeys * sizeof(ScanKeyData));
 
-                       for (i = 0; i < s->numberOfKeys; i++)
-                       {
-                               p->s_internalKey[i].sk_argument = s->keyData[i].sk_argument;
-                               internal_proc = RTMapOperator(s->indexRelation,
-                                                                                         s->keyData[i].sk_attno,
-                                                                                         s->keyData[i].sk_procedure);
-                               ScanKeyEntryInitialize(&(p->s_internalKey[i]),
-                                                                          s->keyData[i].sk_flags,
-                                                                          s->keyData[i].sk_attno,
-                                                                          internal_proc,
-                                                                          s->keyData[i].sk_argument);
-                       }
+               /*
+                * Scans on internal pages use different operators than they
+                * do on leaf pages.  For example, if the user wants all boxes
+                * that exactly match (x1,y1,x2,y2), then on internal pages we
+                * need to find all boxes that contain (x1,y1,x2,y2).
+                */
+               for (i = 0; i < s->numberOfKeys; i++)
+               {
+                       internal_proc = RTMapOperator(s->indexRelation,
+                                                                                 s->keyData[i].sk_attno,
+                                                                                 s->keyData[i].sk_procedure);
+                       ScanKeyEntryInitialize(&(p->s_internalKey[i]),
+                                                                  s->keyData[i].sk_flags,
+                                                                  s->keyData[i].sk_attno,
+                                                                  internal_proc,
+                                                                  s->keyData[i].sk_argument);
                }
        }