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.
This commit is contained in:
Tom Lane 2003-03-23 23:01:03 +00:00
parent cb1672e9f8
commit 0489783011
5 changed files with 63 additions and 72 deletions

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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->currentItemData);
ItemPointerSetInvalid(&s->currentMarkData); ItemPointerSetInvalid(&s->currentMarkData);
if (s->numberOfKeys > 0)
{
memmove(s->keyData,
key,
s->numberOfKeys * sizeof(ScanKeyData));
}
p = (GISTScanOpaque) s->opaque; p = (GISTScanOpaque) s->opaque;
if (p != (GISTScanOpaque) NULL) if (p != (GISTScanOpaque) NULL)
{ {
/* rescan an existing indexscan --- reset state */
gistfreestack(p->s_stack); gistfreestack(p->s_stack);
gistfreestack(p->s_markstk); gistfreestack(p->s_markstk);
p->s_stack = p->s_markstk = (GISTSTACK *) NULL; p->s_stack = p->s_markstk = (GISTSTACK *) NULL;
p->s_flags = 0x0; 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 else
{ {
@ -110,22 +96,28 @@ gistrescan(PG_FUNCTION_ARGS)
s->opaque = p; s->opaque = p;
p->giststate = (GISTSTATE *) palloc(sizeof(GISTSTATE)); p->giststate = (GISTSTATE *) palloc(sizeof(GISTSTATE));
initGISTstate(p->giststate, s->indexRelation); initGISTstate(p->giststate, s->indexRelation);
if (s->numberOfKeys > 0) }
/* /* Update scan key, if a new one is given */
* * Play games here with the scan key to use the Consistent * if (key && s->numberOfKeys > 0)
* function for all comparisons: * 1) the sk_procedure field {
* will now be used to hold the * strategy number * 2) the memmove(s->keyData,
* sk_func field will point to the Consistent function key,
*/ s->numberOfKeys * sizeof(ScanKeyData));
for (i = 0; i < s->numberOfKeys; i++) /*
{ * Play games here with the scan key to use the Consistent
s->keyData[i].sk_procedure = * function for all comparisons: 1) the sk_procedure field
RelationGetGISTStrategy(s->indexRelation, * will now be used to hold the strategy number 2) the
s->keyData[i].sk_attno, * sk_func field will point to the Consistent function
s->keyData[i].sk_procedure); */
s->keyData[i].sk_func = p->giststate->consistentFn[s->keyData[i].sk_attno - 1]; 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(); PG_RETURN_VOID();

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* This file contains only the public interface routines. * This file contains only the public interface routines.
@ -302,10 +302,8 @@ hashrescan(PG_FUNCTION_ARGS)
{ {
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0); IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
ScanKey scankey = (ScanKey) PG_GETARG_POINTER(1); ScanKey scankey = (ScanKey) PG_GETARG_POINTER(1);
HashScanOpaque so = (HashScanOpaque) scan->opaque;
ItemPointer iptr; ItemPointer iptr;
HashScanOpaque so;
so = (HashScanOpaque) scan->opaque;
/* we hold a read lock on the current page in the scan */ /* we hold a read lock on the current page in the scan */
if (ItemPointerIsValid(iptr = &(scan->currentItemData))) if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
@ -321,8 +319,8 @@ hashrescan(PG_FUNCTION_ARGS)
ItemPointerSetInvalid(iptr); ItemPointerSetInvalid(iptr);
} }
/* reset the scan key */ /* Update scan key, if a new one is given */
if (scan->numberOfKeys > 0) if (scankey && scan->numberOfKeys > 0)
{ {
memmove(scan->keyData, memmove(scan->keyData,
scankey, scankey,

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
* index_open - open an index relation by relation OID * 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 * index_rescan - (re)start a scan of an index
* *
* The caller may specify a new set of scankeys (but the number of keys * 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 * cannot change). To restart the scan without changing keys, pass NULL
* an indexscan; see RelationGetIndexScan. * 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 void

View File

@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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)); so->keyData = (ScanKey) palloc(scan->numberOfKeys * sizeof(ScanKeyData));
else else
so->keyData = (ScanKey) NULL; so->keyData = (ScanKey) NULL;
so->numberOfKeys = scan->numberOfKeys;
scan->opaque = so; scan->opaque = so;
} }
@ -420,12 +421,12 @@ btrescan(PG_FUNCTION_ARGS)
* Reset the scan keys. Note that keys ordering stuff moved to * Reset the scan keys. Note that keys ordering stuff moved to
* _bt_first. - vadim 05/05/97 * _bt_first. - vadim 05/05/97
*/ */
so->numberOfKeys = scan->numberOfKeys; if (scankey && scan->numberOfKeys > 0)
if (scan->numberOfKeys > 0)
{ {
memmove(scan->keyData, memmove(scan->keyData,
scankey, scankey,
scan->numberOfKeys * sizeof(ScanKeyData)); scan->numberOfKeys * sizeof(ScanKeyData));
so->numberOfKeys = scan->numberOfKeys;
memmove(so->keyData, memmove(so->keyData,
scankey, scankey,
so->numberOfKeys * sizeof(ScanKeyData)); so->numberOfKeys * sizeof(ScanKeyData));

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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->currentItemData);
ItemPointerSetInvalid(&s->currentMarkData); ItemPointerSetInvalid(&s->currentMarkData);
if (s->numberOfKeys > 0)
{
memmove(s->keyData,
key,
s->numberOfKeys * sizeof(ScanKeyData));
}
p = (RTreeScanOpaque) s->opaque; p = (RTreeScanOpaque) s->opaque;
if (p != (RTreeScanOpaque) NULL) if (p != (RTreeScanOpaque) NULL)
{ {
/* rescan an existing indexscan --- reset state */
freestack(p->s_stack); freestack(p->s_stack);
freestack(p->s_markstk); freestack(p->s_markstk);
p->s_stack = p->s_markstk = (RTSTACK *) NULL; p->s_stack = p->s_markstk = (RTSTACK *) NULL;
p->s_flags = 0x0; p->s_flags = 0x0;
for (i = 0; i < s->numberOfKeys; i++)
p->s_internalKey[i].sk_argument = s->keyData[i].sk_argument;
} }
else else
{ {
@ -106,28 +98,32 @@ rtrescan(PG_FUNCTION_ARGS)
p->s_flags = 0x0; p->s_flags = 0x0;
s->opaque = p; s->opaque = p;
if (s->numberOfKeys > 0) if (s->numberOfKeys > 0)
{
p->s_internalKey = (ScanKey) palloc(sizeof(ScanKeyData) * s->numberOfKeys); p->s_internalKey = (ScanKey) palloc(sizeof(ScanKeyData) * s->numberOfKeys);
}
/* /* Update scan key, if a new one is given */
* Scans on internal pages use different operators than they if (key && s->numberOfKeys > 0)
* do on leaf pages. For example, if the user wants all boxes {
* that exactly match (x1,y1,x2,y2), then on internal pages we memmove(s->keyData,
* need to find all boxes that contain (x1,y1,x2,y2). key,
*/ s->numberOfKeys * sizeof(ScanKeyData));
for (i = 0; i < s->numberOfKeys; i++) /*
{ * Scans on internal pages use different operators than they
p->s_internalKey[i].sk_argument = s->keyData[i].sk_argument; * do on leaf pages. For example, if the user wants all boxes
internal_proc = RTMapOperator(s->indexRelation, * that exactly match (x1,y1,x2,y2), then on internal pages we
s->keyData[i].sk_attno, * need to find all boxes that contain (x1,y1,x2,y2).
s->keyData[i].sk_procedure); */
ScanKeyEntryInitialize(&(p->s_internalKey[i]), for (i = 0; i < s->numberOfKeys; i++)
s->keyData[i].sk_flags, {
s->keyData[i].sk_attno, internal_proc = RTMapOperator(s->indexRelation,
internal_proc, s->keyData[i].sk_attno,
s->keyData[i].sk_argument); 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);
} }
} }