aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-03-23 23:01:03 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-03-23 23:01:03 +0000
commit0489783011ee277476bd9076767b39f08c0e0cd1 (patch)
tree112fe43c1144a4381569b56343ce7f910565de5a
parentcb1672e9f826ba63bbb9b7c2551307df9f440f57 (diff)
downloadpostgresql-0489783011ee277476bd9076767b39f08c0e0cd1.tar.gz
postgresql-0489783011ee277476bd9076767b39f08c0e0cd1.zip
Adjust amrescan code so that it's allowed to call index_rescan with a
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.
-rw-r--r--src/backend/access/gist/gistscan.c56
-rw-r--r--src/backend/access/hash/hash.c10
-rw-r--r--src/backend/access/index/indexam.c10
-rw-r--r--src/backend/access/nbtree/nbtree.c7
-rw-r--r--src/backend/access/rtree/rtscan.c54
5 files changed, 64 insertions, 73 deletions
diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c
index 9c1c92a880a..8a23b9b115c 100644
--- a/src/backend/access/gist/gistscan.c
+++ b/src/backend/access/gist/gistscan.c
@@ -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();
diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c
index 705041f7d27..f3534d2e174 100644
--- a/src/backend/access/hash/hash.c
+++ b/src/backend/access/hash/hash.c
@@ -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,
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index d045bafc1c8..2f0c6aac529 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -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
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index b1722244e6d..a35901b47c6 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -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));
diff --git a/src/backend/access/rtree/rtscan.c b/src/backend/access/rtree/rtscan.c
index 52aedeae2b8..a0b9883cfe8 100644
--- a/src/backend/access/rtree/rtscan.c
+++ b/src/backend/access/rtree/rtscan.c
@@ -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);
}
}