Adjust amrescan code so that it's allowed to call index_rescan with a
authorTom Lane
Sun, 23 Mar 2003 23:01:03 +0000 (23:01 +0000)
committerTom Lane
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);
        }
    }